正如在这个问题中一样,我一直在阅读 PoEAA 并想知道是否可以将参照完整性检查推迟到 MySQL 中提交。
当我想在同一个提交中插入一堆产品和相关产品时,我遇到了这个问题。即使在事务中,当我尝试插入related_products
连接表时也会遇到约束错误。
如果有帮助,我将使用 PHP PDO 进行数据库连接。
我很感激你能提供的任何帮助。
正如在这个问题中一样,我一直在阅读 PoEAA 并想知道是否可以将参照完整性检查推迟到 MySQL 中提交。
当我想在同一个提交中插入一堆产品和相关产品时,我遇到了这个问题。即使在事务中,当我尝试插入related_products
连接表时也会遇到约束错误。
如果有帮助,我将使用 PHP PDO 进行数据库连接。
我很感激你能提供的任何帮助。
看来我的答案在这里...
与一般的 MySQL 一样,在插入、删除或更新许多行的 SQL 语句中,InnoDB 逐行检查 UNIQUE 和 FOREIGN KEY 约束。在执行外键检查时,InnoDB 在它必须查看的子记录或父记录上设置共享行级锁。InnoDB 立即检查外键约束;检查不推迟到事务提交。根据 SQL 标准,默认行为应该是延迟检查。也就是说,仅在处理完整个 SQL 语句后才检查约束。在 InnoDB 实现延迟约束检查之前,有些事情是不可能的,例如删除使用外键引用自身的记录。
回到绘图板。
如果你问 MySQL 是否支持DEFERRABLE
外键的属性(包括 option INITIALLY DEFERRED
),那么答案是明确的不。
您不能将约束检查推迟到 MySQL 中的提交时间。
而且-正如您已经指出的那样-它们总是在“行级别”而不是“语句级别”进行评估。
您可以通过设置服务器变量临时禁用外键检查来处理 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;