如何在MySQL中暂时禁用外键约束?
是否有可能暂时禁用MySQL中的约束?
我有两个Django模型,每个都有一个ForeignKey到另一个。 由于ForeignKey约束,删除模型的实例会返回一个错误:
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()
是否有可能暂时禁用约束和删除呢?
尝试DISABLE KEYS
或
SET FOREIGN_KEY_CHECKS=0;
确保
SET FOREIGN_KEY_CHECKS=1;
后。
要全局closures外键约束,请执行以下操作:
SET GLOBAL FOREIGN_KEY_CHECKS=0;
并记住当你完成后把它放回去
SET GLOBAL FOREIGN_KEY_CHECKS=1;
警告:您只应在做单用户模式维护时执行此操作。 因为这可能会导致数据不一致。 例如,当您使用mysqldump输出上传大量数据时,这将非常有帮助。
我通常只需要禁用外键约束,当我想截断一个表,并且因为我不断回到这个答案这是为了未来我:
SET FOREIGN_KEY_CHECKS=0; TRUNCATE TABLE table; SET FOREIGN_KEY_CHECKS=1;
而不是禁用您的约束,永久修改它为ON DELETE SET NULL。 这将完成一个类似的事情,你不必打开和closures钥匙检查。 像这样:
ALTER TABLE tablename1 DROP FOREIGN KEY fk_name1; //get rid of current constraints ALTER TABLE tablename2 DROP FOREIGN KEY fk_name2; ALTER TABLE tablename1 ADD FOREIGN KEY (table2_id) REFERENCES table2(id) ON DELETE SET NULL //add back constraint ALTER TABLE tablename2 ADD 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 )。
如果键字段可以为空,那么您也可以在尝试删除之前将该值设置为空:
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()
将外键约束设置为0不是一个好主意,因为如果这样做,数据库不会确保它不违反参照完整性。 这可能会导致数据不准确,误导或不完整。
由于某个原因,您创build了一个外键:因为子列中的所有值应与父列中的值相同。 如果没有外键约束,则子行的值可能不在父行中,这会导致数据不准确。
例如,假设您有一个供学生login的网站,每个学生都必须以用户身份注册一个帐户。 你有一个用户ID的表,用户ID是主键; 另外还有一张学生账号表,学号为列。 由于每个学生都必须有一个用户标识,因此从学生帐户的学生标识表中引用用户标识表中的主键用户标识的外键是有意义的。 如果没有外键检查,学生最终可能会有一个学生ID和没有用户ID,这意味着学生可以得到一个帐户,而不是一个用户,这是错误的。
想象一下,如果这发生在大量的数据。 这就是为什么你需要外键检查。
最好弄清楚是什么导致了错误。 很可能,您正在尝试从父行中删除而不从子行中删除。 在从父行删除之前尝试从子行删除。
在phpMyAdmin中,您可以select多行,然后单击删除操作。 您将进入一个列出删除查询的屏幕,您可以取消勾选外键检查,然后单击是执行它们。
这将使您能够删除行,即使有一个ON DELETE限制约束。
一个非常简单的phpmyadmin解决scheme:在你的表中,进入SQL选项卡,编辑你想要运行的SQL命令之后,在GO旁边有一个checkbox“启用外键检查”。禁用此checkbox并运行你的SQL。 它会被自动重新检查。