我的项目中有几个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 | |
+-----------------------------+-------------------------------+----------+---------+
答案 0 :(得分:0)
您必须反转外键。
Reviews.AgreeID -> Agreements.ID
ActionableDates.AgreeID -> Agreements.ID
子表必须指向父表,反之亦然
答案 1 :(得分:0)
您在“协议”表中
---------------------------------------------------
ID UnitID Report Protected TenantID
---------------------------------------------------
您需要检查从哪里获得Unit ID和TenantID,它们可能是其他表(例如“ Unit”和“ Tenant”)的主键。在这种情况下,您需要在这些表中有记录,那么只有您可以在该表中引用它。