web-dev-qa-db-ja.com

MySQLでは、コミットまで参照整合性チェックを延期できますか

この質問 のように、私はPoEAAを読んでいて、MySQLでコミットするまで参照整合性チェックを延期することが可能かどうか疑問に思っています。

一連の製品と関連製品を同じコミットに挿入したいときに、この問題に遭遇しました。トランザクション内でも、related_products結合テーブルに挿入しようとすると、制約エラーが発生します。

それが役立つ場合は、データベース接続にPHP PDOを使用しています。

私はあなたが提供できるあらゆる助けに感謝します。

50
Ross McFarlane

私の答えは here ...のようです.

一般にMySQLと同様に、多くの行を挿入、削除、または更新するSQLステートメントでは、InnoDBは行ごとにUNIQUEおよびFOREIGN KEY制約をチェックします。外部キーチェックを実行すると、InnoDBは、参照する必要がある子レコードまたは親レコードに共有行レベルのロックを設定します。 InnoDBはすぐに外部キー制約をチェックします。チェックはトランザクションコミットに延期されません。SQL標準によれば、デフォルトの動作は据え置きチェックである必要があります。つまり、SQLステートメント全体が処理された後でのみ制約がチェックされます。 InnoDBが遅延制約チェックを実装するまで、外部キーを使用してそれ自体を参照するレコードを削除するなど、いくつかのことが不可能になります。

ふりだしに戻る。

64
Ross McFarlane

MySQLが外部キー(オプションINITIALLY DEFERREDを含む)のDEFERRABLE属性をサポートするかどうかを尋ねている場合、答えは明らかです。

MySQLのコミット時まで制約チェックを延期することはできません。

そして、すでに指摘したように、それらは常に「ステートメントレベル」ではなく「行レベル」で評価されます。

14

サーバー変数を設定して外部キーチェックを一時的に無効にすることにより、このinnodbエンジンの制限を処理できます。

set foreign_key_checks=0;

MySQLマニュアルから:

mysqldumpはまた、ダンプファイルにテーブルの正しい定義を生成し、外部キーを忘れません。

外部キー関係のあるテーブルのダンプファイルを簡単にリロードできるように、mysqldumpは自動的にダンプ出力にステートメントを含めて、foreign_key_checksを0に設定します。これにより、ダンプがリロードされるときにテーブルを特定の順序でリロードする必要がある問題が回避されます。この変数を手動で設定することも可能です。

mysql> SET foreign_key_checks = 0;
mysql> SOURCE dump_file_name;
mysql> SET foreign_key_checks = 1;
10
Thava