与this question一样,我一直在阅读PoEAA,并想知道在MySQL中提交之前是否可以推迟参照完整性检查。
当想要在同一次提交中插入一堆产品和相关产品时,我遇到了这个问题。即使在事务中,当我尝试插入related_products
连接表时,我也会遇到约束错误。
如果有帮助,我正在使用PHP PDO进行数据库连接。
我很感激您提供的任何帮助。
答案 0 :(得分:60)
看起来我的回答是here ...
与MySQL一样,在插入,删除或更新许多行的SQL语句中,InnoDB逐行检查UNIQUE和FOREIGN KEY约束。执行外键检查时,InnoDB会在必须查看的子记录或父记录上设置共享行级锁。 InnoDB立即检查外键约束;检查不会延迟到事务提交。 根据SQL标准,默认行为应该是延迟检查。也就是说,只有在处理完整个SQL语句后才会检查约束。在InnoDB实现延迟约束检查之前,有些事情是不可能的,例如删除使用外键引用自身的记录。
回到绘图板。
答案 1 :(得分:14)
如果您询问MySQL是否支持外键的DEFERRABLE
属性(包括选项INITIALLY DEFERRED
),那么答案是明确的。
在MySQL中提交时间之前,不能推迟约束检查。
并且 - 正如您已经指出的那样 - 它们总是在“行级别”而非“语句级别”进行评估。
答案 2 :(得分:10)
您可以通过设置服务器变量暂时禁用外键检查来处理innodb引擎的此限制:
set foreign_key_checks=0;
来自MySQL手册:
mysqldump还会在转储文件中生成正确的表定义,并且不会忘记外键。
为了更容易为具有外键关系的表重新加载转储文件,mysqldump会自动在转储输出中包含一个语句,以将foreign_key_checks设置为0.这样可以避免在转储时必须按特定顺序重新加载表的问题被重新加载。也可以手动设置此变量:
mysql> SET foreign_key_checks = 0;
mysql> SOURCE dump_file_name;
mysql> SET foreign_key_checks = 1;