如何应用约束并使用“不采取行动”规则意味着不采取行动

时间:2018-10-29 15:46:14

标签: mysql innodb

我正在尝试弄清外键约束的正确用法,并在涉及“ ON DELETE”,“ NO ACTION”时保持空白 我将保持通用性,因为iis非常简单,而无需深入研究有限的细节。

  

我有一个父表,其中有5个子表-存在   所有表中的数据(不是新的数据库版本)。我要设定   符合逻辑,可以满足我的客户需求,而且我期望!   所有父子表之间存在一对多关系   因此:到父表的记录可能为零或很多   主键记录永远不会有没有的子记录   与父记录相关(已检查ive以确保是这样)。

由于任何子表中现在都可能(可能有)父记录没有子记录,因此设置“父子约束”失败,好了,我明白为什么了,没问题。 因此,病态地设置了“孩子到父母”的约束条件:

  • 如果子记录(Fk)已更新,请更新父记录(PK)。
  • 如果删除了子记录(Fk),则允许删除该子记录,但不对父(Pk)记录采取任何操作(超级重要!)
  • 如果删除了父记录,则删除它以及所有子表中的所有相关子记录

但是,即时通讯正在SO和MySQL文档上读取表示“ NO ACTION”与“ RESTRICT”相同的线程,如果我无法删除子记录,它将引起问题。 我在PHP代码中主要使用'INSERT INTO'语句和ON DUPLICATE KEY UPDATE'语句。 我的倾向是从数据库级别完全删除外键约束,而只是在PHP / PDO中强制执行我想实现的目标。 我实际上正在使用外键约束,因为我认为我必须但没有真正明白这一点,因为无论如何都应该更新主键。

什么是最好的方法。如果“不采取行动”实际上是预防而不是保护,那是个好的用例。

2 个答案:

答案 0 :(得分:1)

  

'NO ACTION'与'RESTRICT'相同,如果我无法删除子记录,它将引起问题。

那不是那个条件的意思。它不会阻止您删除 child 记录,而是会阻止您仅在存在依赖于父记录的子记录的情况下删除 parent 记录。

示例:

OrdersLineItems具有一对多关系,而LineItems中的外键具有限制选项。

CREATE TABLE Orders (
  order_id INT NOT NULL,
  PRIMARY KEY (order_id)
);

CREATE TABLE LineItems (
  lineitem_id INT NOT NULL,
  order_id INT NOT NULL,
  PRIMARY KEY (lineitem_id),
  FOREIGN KEY (order_id) REFERENCES Orders (order_id) ON DELETE RESTRICT
);

创建一些测试数据:

mysql> INSERT INTO Orders SET order_id = 123;
Query OK, 1 row affected (0.02 sec)

mysql> INSERT INTO LineItems SET lineitem_id = 1, order_id = 123;
Query OK, 1 row affected (0.02 sec)

我们无法删除订单记录,因为有一个LineItem取决于它:

mysql> DELETE FROM Orders WHERE order_id = 123;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`test`.`lineitems`, CONSTRAINT `lineitems_ibfk_1` FOREIGN KEY (`order_id`) REFERENCES `Orders` (`order_id`))

但是我们可以随时删除LineItems记录:

mysql> DELETE FROM LineItems WHERE order_id = 123;
Query OK, 1 row affected (0.01 sec)

现在没有引用Orders记录的LineItems记录,我们也可以删除该记录:

mysql> DELETE FROM Orders WHERE order_id = 123;
Query OK, 1 row affected (0.01 sec)

答案 1 :(得分:0)

@Bill Karwin及其问题的贡献者。从那以后,我意识到数据库设置不正确,这就是为什么我需要删除FK约束才能使用它。从MS Access迁移了数据库,并且由于一些数据类型的差异,将DB导入mySQL时如果不执行此导入操作,则将关闭外键约束检查。仅此一项就表明在MS Access中设置约束规则存在问题。

现在在MySQL中使用导出的数据库,显示出许多孤立记录和索引字段,这些记录和索引字段为null或为空,已经违反了FK约束! -在修复这些问题并适当地规范化数据库/表之后,这里提出了建议。

感谢您的输入。