我正在尝试弄清外键约束的正确用法,并在涉及“ ON DELETE”,“ NO ACTION”时保持空白 我将保持通用性,因为iis非常简单,而无需深入研究有限的细节。
我有一个父表,其中有5个子表-存在 所有表中的数据(不是新的数据库版本)。我要设定 符合逻辑,可以满足我的客户需求,而且我期望! 所有父子表之间存在一对多关系 因此:到父表的记录可能为零或很多 主键记录永远不会有没有的子记录 与父记录相关(已检查ive以确保是这样)。
由于任何子表中现在都可能(可能有)父记录没有子记录,因此设置“父子约束”失败,好了,我明白为什么了,没问题。 因此,病态地设置了“孩子到父母”的约束条件:
但是,即时通讯正在SO和MySQL文档上读取表示“ NO ACTION”与“ RESTRICT”相同的线程,如果我无法删除子记录,它将引起问题。 我在PHP代码中主要使用'INSERT INTO'语句和ON DUPLICATE KEY UPDATE'语句。 我的倾向是从数据库级别完全删除外键约束,而只是在PHP / PDO中强制执行我想实现的目标。 我实际上正在使用外键约束,因为我认为我必须但没有真正明白这一点,因为无论如何都应该更新主键。
什么是最好的方法。如果“不采取行动”实际上是预防而不是保护,那是个好的用例。
答案 0 :(得分:1)
'NO ACTION'与'RESTRICT'相同,如果我无法删除子记录,它将引起问题。
那不是那个条件的意思。它不会阻止您删除 child 记录,而是会阻止您仅在存在依赖于父记录的子记录的情况下删除 parent 记录。
示例:
表Orders
与LineItems
具有一对多关系,而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约束! -在修复这些问题并适当地规范化数据库/表之后,这里提出了建议。
感谢您的输入。