mysql外键约束阻止在父表中插入查询

eulz3vhy  于 2021-06-18  发布在  Mysql
关注(0)|答案(2)|浏览(301)

我的项目中有几个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 ....

这些表是从msaccess迁移过来的,我在过去的几个月里为客户机编写了一个应用程序,主要用于读取和更新数据。这工作正常,但现在在尝试插入新记录时,外键约束会阻止任何新协议(父表)的插入,因为所有子表(reviews和actionabledates)上都有更新/删除级联约束。

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

我理解更新删除操作需要有这些约束,以确保没有留下孤立记录。但是,在父表agreements中插入新记录时,这些约束不需要“启动”。
逻辑是子表在操作应用程序的生命周期内的任何时候都添加了记录;因此,如果在那里添加一个新的协议,很可能,最肯定的是,将不会有一个评审记录添加到相应的评审表中。与actionabledates表相同。这些“事件”在创建协议(记录)后随时发生。
是否有任何类型的mysql约束操作可以用来保留更新/删除时的级联,但允许我在父表中输入新记录??其他任何操作都不能设置为没有错误:“no action”、“set default”、“set null”等。。。
不确定这些限制为什么或如何在原始ms access db中工作,但它们在逻辑上毫无意义。除了为子表创建虚拟记录之外???
我现在删除了所有外键限制,并使用事务pdomsql定义了一些逻辑。

编辑协议表架构

协议

+-----------------------------+-------------------------------+----------+---------+
| 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      |         |
+-----------------------------+-------------------------------+----------+---------+
hjzp0vay

hjzp0vay1#

你得把外键倒过来。

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

子表必须指向父表,反之亦然

qgelzfjb

qgelzfjb2#

在您的协议表中

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

您需要检查unit id和tenantid的位置,它们可能是其他表(如“unit”和“tenant”)的主键。在这种情况下,您需要在这些表中有记录,然后只有您可以在这个表中引用它。

相关问题