MySQL外键约束可防止在父表中进行插入查询

时间:2018-10-08 10:39:55

标签: mysql innodb

我的项目中有几个MySQL InnoDB表。大多数查询使用父表的主键作为查询的基础,此处显示了一个示例:

Agreements (Parent Table)
---------------------------------------------------
ID       UnitID    Report   Protected   TenantID
---------------------------------------------------
19       288       1        0           13
20       287       1        0           9
21       286       1        0           9



Reviews (Child Table)
-----------------------------------------------------
ID    AgreeID     FrequencyID      ReviewDate
-----------------------------------------------------
10    11        4              2015-04-25 00:00:00             
14    35        4              2007-03-08 00:00:00     
15    18        4              2017-03-01 00:00:00



ActionableDates (Child Table)
------------------------------------------------------------
ID    AgreeID   CriticalDate           Note
------------------------------------------------------------
3     11        2013-04-24 00:00:00    ... yadda yadda ....
7     48        2017-11-25 00:00:00    ... yadda yadda ....
8     47        2014-05-21 00:00:00    ... yadda yadda .... 
9     14        2014-06-24 00:00:00    ... yadda yadda ....

这些表是从MS Access迁移而来的,我在过去的几个月里花了很多时间为客户端编写一个应用程序,该应用程序主要读取和更新数据。 这很好用,但是现在当尝试插入新记录时,由于所有子表(Reviews和ActionableDates)上都有UPDATE / DELETE CASCADE约束,因此外键约束阻止了新协议(父表)的任何插入。

Agreements.ID -> Reviews.AgreeID
Agreements.ID -> ActionableDates.AgreeID

我知道更新删除操作需要具有这些约束,以确保不会留下孤立记录。 但是,当在父表“协议”中插入新记录时,这些矛盾就不需要“踢”了。

逻辑是,子表在操作应用程序的生存期内随时可以添加记录;因此,如果在那里添加新协议,很可能会 不是要添加到相应“评论”表的评论记录。与ActionableDates表相同。这些“事件”在创建协议(记录)后的任何时间发生。

是否可以使用这些MySQL约束进行任何形式的操作来保留CASCADE ON Update / Delete,但允许我在Parent表中输入新记录? 没有其他任何操作都不能设置为没有错误:“无操作”,“设置默认值”,“设置为空”等...

不确定这些限制为何或如何在原始MS Access DB中起作用,但是从逻辑上讲它们没有任何意义。除了在子表中创建虚拟记录之外?

我现在已经删除了所有外键约束,并使用Transactional PDOMySQL定义了一些逻辑。

编辑-协议表架构

协议

+-----------------------------+-------------------------------+----------+---------+
| Column                      | Type                          | Nullable | Default |
+-----------------------------+-------------------------------+----------+---------+
| ID (PRIMARY)                | int(11)  Auto Increment       | No       |         |
+-----------------------------+-------------------------------+----------+---------+
| UnitID                      | int(11)                       | Yes      |         |
+-----------------------------+-------------------------------+----------+---------+
| Report                      | tinyint(4)                    | Yes      | 0       |
+-----------------------------+-------------------------------+----------+---------+
| Protected                   | tinyint(4)                    | Yes      | 0       |
+-----------------------------+-------------------------------+----------+---------+
| TenantID                    | int(11)                       | Yes      |         |
+-----------------------------+-------------------------------+----------+---------+
| RentNotes                   | longtext  utf8_general_ci     | Yes      |         |
+-----------------------------+-------------------------------+----------+---------+
| Dilapid                     | varchar(255)  utf8_general_ci | Yes      |         |
+-----------------------------+-------------------------------+----------+---------+
| AgreeDated                  | datetime                      | Yes      |         |
+-----------------------------+-------------------------------+----------+---------+
| AgreeStartDate              | datetime                      | Yes      |         |
+-----------------------------+-------------------------------+----------+---------+
| AgreeEndDate                | datetime                      | Yes      |         |
+-----------------------------+-------------------------------+----------+---------+

2 个答案:

答案 0 :(得分:0)

您必须反转外键。

Reviews.AgreeID         -> Agreements.ID
ActionableDates.AgreeID -> Agreements.ID

表必须指向表,反之亦然

答案 1 :(得分:0)

您在“协议”表中

---------------------------------------------------
ID       UnitID    Report   Protected   TenantID
---------------------------------------------------

您需要检查从哪里获得Unit ID和TenantID,它们可能是其他表(例如“ Unit”和“ Tenant”)的主键。在这种情况下,您需要在这些表中有记录,那么只有您可以在该表中引用它。