web-dev-qa-db-ja.com

MySQLの外部キー制約を一時的に無効にする方法

MySQLの制約を一時的に無効にすることは可能ですか?

私は2つの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()

一時的に制約を無効にして削除することは可能ですか?

555
jul

DISABLE KEYSを試すか 

SET FOREIGN_KEY_CHECKS=0;

に確かめなさい

SET FOREIGN_KEY_CHECKS=1;

後に。

1255
Andrew Campbell

グローバルに外部キー制約を無効にするには、以下行います。

SET GLOBAL FOREIGN_KEY_CHECKS=0;

完了したら元に戻すことを忘れないでください

SET GLOBAL FOREIGN_KEY_CHECKS=1;

警告:あなたがシングルユーザーモードのメンテナンスをしているときだけこれをするべきです。データの不整合が生じる可能性があるため。たとえば、mysqldump出力を使用して大量のデータをアップロードしているときに非常に役立ちます。

116
berniey

私は通常テーブルを切り捨てたいときにのみ外部キー制約を無効にします、そして私はこの答えに戻り続けているのでこれは将来の私のためです:

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

制約を無効にする代わりに、恒久的に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

これ( 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 )。

24
dnagirl

グローバルに外部キー制約を無効にするには

SET GLOBAL FOREIGN_KEY_CHECKS = 0;

アクティブな外部キー制約の場合

SET GLOBAL FOREIGN_KEY_CHECKS = 1;
8
Umar Tariq

Phpmyadminを使った非常に簡単な解決策:あなたのテーブルの中で、実行したいSQLコマンドを編集した後、GOの隣にチェックボックス '外部キーチェックを有効にする'がありますSQLです。自動的に再確認されます。

6
svin

キーフィールドがNULL可能である場合は、それを削除する前に値を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()
3
Chanoch

私にとっては、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;
2
RotS

外部キー制約を0に設定しても、データベースが参照整合性に違反していないことをデータベースが保証しないため、お勧めできません。これは不正確、誤解を招く、または不完全なデータにつながる可能性があります。

なぜなら、子列のすべての値は親列の値と同じになるからです。外部キー制約がない場合、子行は親行にない値を持つ可能性があります。これは不正確なデータにつながります。

たとえば、学生がログインするためのWebサイトがあり、すべての学生がユーザーとしてアカウントに登録する必要があるとします。ユーザーIDを主キーとして、ユーザーID用のテーブルが1つあります。列として学生IDを持つ、学生アカウント用の別のテーブル。すべての学生はユーザーIDを持っている必要があるため、学生アカウントテーブルの学生IDを、ユーザーIDテーブルの主キーユーザーIDを参照する外部キーにすることは意味があります。外部キーチェックがない場合、学生は学生IDとユーザーIDを持たなくなる可能性があります。つまり、学生はユーザーにならなくてもアカウントを取得できますが、これは誤りです。

大量のデータが発生した場合を想像してください。外部キーチェックが必要なのはそのためです。

エラーの原因を突き止めることが最善です。ほとんどの場合、子行から削除せずに親行から削除しようとしています。親行から削除する前に、子行から削除してみてください。 

0
Valencia Starr

PhpMyAdminでは、複数の行を選択してから削除アクションをクリックできます。削除クエリを一覧表示する画面に入ります。外部キーチェックをオフにして、はいをクリックして実行します。 

これにより、ON DELETE制限がある場合でも行を削除できます。 

0
Julian