如何临时禁用MySQL中的外键约束?

jul*_*jul 605 mysql sql django django-models

是否可以暂时禁用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()
Run Code Online (Sandbox Code Playgroud)

是否可以暂时禁用约束并删除?

And*_*ell 1403

试试DISABLE KEYS

SET FOREIGN_KEY_CHECKS=0;
Run Code Online (Sandbox Code Playgroud)

确保

SET FOREIGN_KEY_CHECKS=1;
Run Code Online (Sandbox Code Playgroud)

后.

  • 我相信这是每次会议. (22认同)
  • http://serverfault.com/questions/291100/with-mysql-how-long-does-an-alter-table-disable-keys-statement-last#comment820481_291100,还要注意你[**不能**`禁用对于Innodb的密钥`](http://serverfault.com/questions/234893/how-to-disable-keys-in-mysql-innodb/234901#comment820478_234901) (13认同)
  • 这是为mysql整体设置还是仅为该会话设置的东西? (11认同)
  • http://stackoverflow.com/questions/8538636/mysql-set-foreign-key-checks (2认同)
  • 我可以为单个表禁用 FOREIGN_KEY_CHECKS 吗? (2认同)
  • 为了澄清@Pacerier的评论:对于Innodb,你不能`DISABLE KEYS`。但是你*可以*完成这个问题中所要求的,使用显示的其他命令:`SET FOREIGN_KEY_CHECKS=0;`(我一开始以为他是说没有办法完成这个。) (2认同)

ber*_*iey 139

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

SET GLOBAL FOREIGN_KEY_CHECKS=0;
Run Code Online (Sandbox Code Playgroud)

并记得在完成后将其设置回来

SET GLOBAL FOREIGN_KEY_CHECKS=1;
Run Code Online (Sandbox Code Playgroud)

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

  • @hexnet不同之处在于,只需`SET FOREIGN_KEY_CHECKS`更改_current connection_的值,而`SET GLOBAL ..`更改_all connections_的值,包括将来的连接.如果你只是在一个窗口中执行`SET FOREIGN..`,那么尝试在不同的窗口(通过不同的连接)中应用该语句,那里的值没有改变.使用`GLOBAL`,同一个变量对两个连接都具有相同的值. (7认同)
  • 这是我需要知道的,所以这不是很好的练习,但是这个人的答案应该得分更高...... (2认同)

Ant*_*oCS 50

我通常只在我要截断表时才禁用外键约束,因为我不断回到这个答案,这是为了将来我:

SET FOREIGN_KEY_CHECKS=0;
TRUNCATE TABLE table;
SET FOREIGN_KEY_CHECKS=1;
Run Code Online (Sandbox Code Playgroud)


dna*_*irl 26

不是禁用约束,而是永久地将其修改为ON DELETE SET NULL.这将完成类似的事情,你不必打开和关闭键检查.像这样:

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
Run Code Online (Sandbox Code Playgroud)

请阅读此内容(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).

  • 小心改变表可能需要很长时间,最好将`FOREIGN_KEY_CHECKS`的服务器全局设置为0,并在脏工作完成后将其放回原处.除此之外它可能会锁定写表. (5认同)

Uma*_*riq 13

要全局关闭外键约束:

SET GLOBAL FOREIGN_KEY_CHECKS = 0;
Run Code Online (Sandbox Code Playgroud)

并用于活动外键约束

SET GLOBAL FOREIGN_KEY_CHECKS = 1;
Run Code Online (Sandbox Code Playgroud)

  • 这似乎是[来自@berniey的现有旧答案]的精确重复(/sf/answers/1722151511/) (3认同)

小智 9

一个非常简单的解决方案,使用phpmyadmin:在你的表中,转到SQL选项卡,在编辑要运行的SQL命令后,在GO旁边有一个复选框'启用外键检查'.禁用此复选框并运行你的SQL.然后会自动重新检查.

  • 谢谢!解决方案的确是SET FOREIGN_KEY_CHECKS = 0; ..... SET FOREIGN_KEY_CHECKS = 1;`在PHPMyAdmin中对我不起作用,因为我忘记了取消选中“启用外键检查”复选框。在PHPMyAdmin中,您可以跳过这些SET命令,而只需取消选中该复选框。 (3认同)

Rot*_*otS 8

对我来说只是SET FOREIGN_KEY_CHECKS=0;不够。我仍然有一个com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException.

我不得不添加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;
Run Code Online (Sandbox Code Playgroud)


Jul*_*ian 5

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

在此输入图像描述

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

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