748

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

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

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

4

10 に答える 10

1625

試してみるDISABLE KEYS

SET FOREIGN_KEY_CHECKS=0;

必ず

SET FOREIGN_KEY_CHECKS=1;

後。

于 2013-03-19T14:07:45.653 に答える
169

外部キー制約をグローバルにオフにするには、次の手順を実行します。

SET GLOBAL FOREIGN_KEY_CHECKS=0;

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

SET GLOBAL FOREIGN_KEY_CHECKS=1;

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

于 2014-07-07T02:05:19.477 に答える
66

通常、テーブルを切り捨てたい場合にのみ外部キー制約を無効にします。この回答に戻ってくるので、これは将来の私のためです:

SET FOREIGN_KEY_CHECKS=0;
TRUNCATE TABLE table;
SET FOREIGN_KEY_CHECKS=1;
于 2015-03-25T16:48:42.223 に答える
28

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

于 2013-03-19T14:33:29.117 に答える
23

外部キー制約をグローバルにオフにするには:

SET GLOBAL FOREIGN_KEY_CHECKS = 0;

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

SET GLOBAL FOREIGN_KEY_CHECKS = 1;
于 2018-01-11T09:49:24.543 に答える
3

phpMyAdminでは、複数の行を選択してから削除アクションをクリックできます。削除クエリを一覧表示する画面に入ります。次のようになります。

ここに画像の説明を入力

「外部キーチェックを有効にする」チェックボックスをオフにし、クリックしYesて実行してください。

これにより、ON DELETE 制限制約があっても行を削除できます。

于 2015-12-31T10:57:47.703 に答える
3

キー フィールドが 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()
于 2014-04-30T21:18:22.603 に答える
-2

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

外部キーを作成する理由は、子列のすべての値が親列の値と同じであるためです。外部キー制約がない場合、親行にない値が子行に含まれる可能性があり、データが不正確になる可能性があります。

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

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

エラーの原因を特定することをお勧めします。ほとんどの場合、子行から削除せずに親行から削除しようとしています。親行から削除する前に、子行から削除してみてください。

于 2015-01-14T10:21:37.303 に答える