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

本文翻译自:How to temporarily disable a foreign key constraint in MySQL?

Is it possible to temporarily disable constraints in MySQL? 是否可以在MySQL中暂时禁用约束?

I have two Django models, each with a ForeignKey to the other one. 我有两个Django模型,每个模型都有一个外键。 Deleting instances of a model returns an error because of the ForeignKey constraint: 由于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()

Is it possible to temporarily disable constraints and delete anyway? 是否可以暂时禁用约束并仍然删除?


#1楼

参考:https://stackoom.com/question/132gz/如何在MySQL中暂时禁用外键约束


#2楼

Try DISABLE KEYS or 尝试DISABLE KEYS

SET FOREIGN_KEY_CHECKS=0;

make sure to 确保

SET FOREIGN_KEY_CHECKS=1;

after. 后。


#3楼

Instead of disabling your constraint, permanently modify it to ON DELETE SET NULL. 与其禁用您的约束,不如将其永久修改为ON DELETE SET NULL。 That will accomplish a similar thing and you wouldn't have to turn key checking on and off. 这将完成类似的事情,而您不必打开和关闭按键检查。 Like so: 像这样:

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

Have a read of this ( http://dev.mysql.com/doc/refman/5.5/en/alter-table.html ) and this ( http://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.html ). 阅读此内容( 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 )。


#4楼

If the key field is nullable, then you can also set the value to null before attempting to delete it: 如果键字段可为空,则还可以在尝试删除它之前将值设置为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()

#5楼

To turn off foreign key constraint globally, do the following: 要全局关闭外键约束,请执行以下操作:

SET GLOBAL FOREIGN_KEY_CHECKS=0;

and remember to set it back when you are done 并记得在完成后将其重新设置

SET GLOBAL FOREIGN_KEY_CHECKS=1;

WARNING: You should only do this when you are doing single user mode maintenance. 警告:仅在进行单用户模式维护时才应这样做。 As it might resulted in data inconsistency. 因为这可能导致数据不一致。 For example, it will be very helpful when you are uploading large amount of data using a mysqldump output. 例如,当您使用mysqldump输出上传大量数据时,这将非常有用。


#6楼

It's not a good idea to set a foreign key constraint to 0, because if you do, your database would not ensure it is not violating referential integrity. 将外键约束设置为0不是一个好主意,因为如果这样做,数据库将无法确保它不会违反参照完整性。 This could lead to inaccurate, misleading, or incomplete data. 这可能会导致数据不准确,误导或不完整。

You make a foreign key for a reason: because all the values in the child column shall be the same as a value in the parent column. 生成外键是有原因的:因为子列中的所有值都应与父列中的值相同。 If there are no foreign key constraints, a child row can have a value that is not in the parent row, which would lead to inaccurate data. 如果没有外键约束,则子行可以具有不在父行中的值,这将导致数据不正确。

For instance, let's say you have a website for students to login and every student must register for an account as a user. 例如,假设您有一个供学生登录的网站,并且每个学生都必须注册一个用户帐户。 You have one table for user ids, with user id as a primary key; 您有一个用于用户ID的表,其中用户ID作为主键。 and another table for student accounts, with student id as a column. 和另一个用于学生帐户的表格,其中以学生ID为列。 Since every student must have a user id, it would make sense to make the student id from the student accounts table a foreign key that references the primary key user id in the user ids table. 由于每个学生都必须有一个用户ID,因此使来自学生帐户表的学生ID成为一个外键,该外键引用用户ID表中的主键用户ID是有意义的。 If there are no foreign key checks, a student could end up having a student id and no user id, which means a student can get an account without being a user, which is wrong. 如果没有外键检查,则学生最终可能会获得一个学生ID和一个用户ID,这意味着该学生可以在没有用户身份的情况下获得帐户,这是错误的。

Imagine if it happens to a large amount of data. 试想一下,如果它发生在大量数据上。 That's why you need the foreign key check. 这就是为什么需要外键检查的原因。

It's best to figure out what is causing the error. 最好找出导致错误的原因。 Most likely, you are trying to delete from a parent row without deleting from a child row. 最有可能的是,您尝试从父行中删除而不从子行中删除。 Try deleting from the child row before deleting from the parent row. 尝试从子行删除,然后再从父行删除。

发布了0 篇原创文章 · 获赞 52 · 访问量 35万+

猜你喜欢

转载自blog.csdn.net/CHCH998/article/details/105613674
今日推荐