首页 > 解决方案 > 如何应用约束和使用 NO Action 规则意味着不采取任何行动

问题描述

我试图澄清外键约束的正确使用,并在'ON DELETE''NO ACTION'时保持空白。我将保持通用性,因为iis非常简单,无需深入研究有限的细节。

我有一个包含 5 个子表的父表 - 所有表中都有现有数据(它不是新的数据库构建)。我想在逻辑上进行设置以适应我的客户需求和我所期望的!因此,所有父表与子表之间存在一对多的关系:可以有零个或多个记录与父表主键记录相关。永远不会有与父记录无关的子记录(我已经检查过以确保是这样)。

由于现在可能(并且可能存在)任何子表中没有子记录的父记录,因此设置父子约束失败,好吧,我明白为什么,没问题。因此,病态地设置了儿童对父母的约束:

但是,我正在阅读 SO 和 MySQL 文档上的线程,其中说“NO ACTION”与“RESTRICT”相同,如果我无法删除子记录,这将导致问题。我在我的 PHP 代码中主要使用“INSERT INTO”语句和 ON DUPLICATE KEY UPDATE' 语句。我的倾向是从数据库级别完全删除外键约束,并像我在我的 PHP/PDO 中所做的那样强制执行我想要实现的目标。我实际上正在使用外键约束,因为我认为我必须这样做,但并没有真正明白这一点,因为无论如何更新主键都不应该发生。

做这个的最好方式是什么。如果它实际上是防止而不是保护,那么“不采取行动”的一个好的用例是什么。

标签: mysqlinnodb

解决方案


“NO ACTION”与“RESTRICT”相同,如果我无法删除子记录,这将导致问题。

那不是那个条件的意思。它不会阻止您删除记录,当且仅当存在依赖于父记录的子记录时,它才会阻止您删除父记录。

例子:

Orders与 具有一对多关系LineItems,并且外键 inLineItems具有限制选项。

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)

我们不能删除 Orders 记录,因为有一个 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)

推荐阅读