如何在MySQL中暂时禁用外键约束?

是否可以暂时禁用MySQL中的约束?

我有两个Django模型,每个都有一个外键。由于外键约束,删除模型的实例会返回错误:

cursor.execute("DELETE FROM myapp_item WHERE n = %s", n)transaction.commit_unless_managed()  #a foreign key constraint fails here
cursor.execute("DELETE FROM myapp_style WHERE n = %s", n)transaction.commit_unless_managed()

是否可以暂时禁用约束并无论如何删除?

803668 次浏览

尝试DISABLE KEYS

SET FOREIGN_KEY_CHECKS=0;

一定要

SET FOREIGN_KEY_CHECKS=1;

之后。

与其禁用约束,不如将其永久修改为ON DELETE SET NULL。这将完成类似的事情,您不必打开和关闭键检查。如下所示:

ALTER TABLE tablename1 DROP FOREIGN KEY fk_name1; //get rid of current constraintsALTER TABLE tablename2 DROP FOREIGN KEY fk_name2;
ALTER TABLE tablename1ADD FOREIGN KEY (table2_id)REFERENCES table2(id)ON DELETE SET NULL  //add back constraint
ALTER TABLE tablename2ADD FOREIGN KEY (table1_id)REFERENCES table1(id)ON DELETE SET NULL //add back other constraint

读一下这个(http://dev.mysql.com/doc/refman/5.5/en/alter-table.html)和这个(http://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.html)。

如果key字段可以为空,那么您也可以在尝试删除它之前将值设置为null:

cursor.execute("UPDATE myapp_item SET myapp_style_id = NULL WHERE n = %s", n)transaction.commit_unless_managed()
cursor.execute("UPDATE myapp_style SET myapp_item_id = NULL WHERE n = %s", n)transaction.commit_unless_managed()
cursor.execute("DELETE FROM myapp_item WHERE n = %s", n)transaction.commit_unless_managed()
cursor.execute("DELETE FROM myapp_style WHERE n = %s", n)transaction.commit_unless_managed()

要全局关闭外键约束,请执行以下操作:

SET GLOBAL FOREIGN_KEY_CHECKS=0;

完成后记得把它放回去

SET GLOBAL FOREIGN_KEY_CHECKS=1;

警告:您只应该在进行单用户模式维护时执行此操作。因为它可能导致数据不一致。例如,当您使用mysqldump输出上传大量数据时,它将非常有帮助。

将外键约束设置为0不是一个好主意,因为如果这样做,数据库将无法确保它没有违反参照完整性。这可能导致数据不准确、误导或不完整。

创建外键是有原因的:因为子列中的所有值都必须与父列中的值相同。如果没有外键约束,子行中的值可能不在父行中,这将导致数据不准确。

例如,假设你有一个供学生登录的网站,每个学生都必须注册一个用户帐户。你有一个表用于用户ID,以用户ID作为主键;另一个表用于学生帐户,以学生ID作为列。由于每个学生都必须有一个用户ID,因此将学生帐户表中的学生ID设置为引用用户ID表中主键用户ID的外键是有意义的。如果没有外键检查,学生最终可能会有一个学生ID而没有用户ID,这意味着学生可以在不成为用户的情况下获得帐户,这是错误的。

想象一下,如果它发生在大量数据上。这就是为什么你需要外键检查。

最好找出导致错误的原因。很可能,您正在尝试从父行中删除而不从子行中删除。在删除父行之前尝试从子行中删除。

我通常只在想要截断表时禁用外键约束,并且由于我一直回到这个答案,这是为了未来的我:

SET FOREIGN_KEY_CHECKS=0;TRUNCATE TABLE table;SET FOREIGN_KEY_CHECKS=1;

phpMyAdmin中,您可以选择多行,然后单击删除操作。您将进入一个列出删除查询的屏幕。它看起来像这样:

输入图片描述

请取消选中“启用外键检查”复选框,然后单击执行它们。

这将使您能够删除行,即使存在ON DELETE限制约束。

一个非常简单的解决方案phpMyAdmin

  • 在您的表中,转到SQL选项卡
  • 编辑要运行的SQL命令后,旁边有一个名为'启用外键检查的复选框。
  • 取消选中此复选框并运行SQL。执行后会自动重新检查。

要全局关闭外键约束:

SET GLOBAL FOREIGN_KEY_CHECKS = 0;

对于活动外键约束:

SET GLOBAL FOREIGN_KEY_CHECKS = 1;

仅仅SET FOREIGN_KEY_CHECKS=0;是不够的。######

我必须添加ALTER TABLE myTable DISABLE KEYS;

所以:

SET FOREIGN_KEY_CHECKS=0;ALTER TABLE myTable DISABLE KEYS;DELETE FROM myTable;ALTER TABLE myTable ENABLE KEYS;SET FOREIGN_KEY_CHECKS=1;