外部キー制約の MySQL 実装は、次の点で SQL 標準と異なります:
親テーブルに同じ参照キー値を持つ複数の行がある場合、
InnoDB
は、同じキー値を持つ他の親行が存在しないかのように外部キーチェックを実行します。 たとえば、RESTRICT
型制約を定義し、複数の親行を持つ子行がある場合、InnoDB
では親行の削除は許可されません。ON UPDATE CASCADE
またはON UPDATE SET NULL
が同じカスケード中に以前に更新していた同じテーブルを更新するように再帰する場合、RESTRICT
のように機能します。 つまり、自己参照型ON UPDATE CASCADE
またはON UPDATE SET NULL
操作は使用できません。 この目的は、カスケード更新で発生する無限ループを回避することです。 反対に、自己参照型ON DELETE SET NULL
は、自己参照型ON DELETE CASCADE
と同様に動作できます。 カスケード操作は、15 レベルよりも深くネストされる可能性がありません。多くの行を挿入、削除、または更新する SQL ステートメントでは、外部キー制約 (一意の制約など) が行ごとにチェックされます。 外部キーチェックを行なっているとき、
InnoDB
は、調べる必要のある子レコードまたは親レコード上に共有行レベルロックを設定します。 MySQL は外部キー制約の確認を即座に行います。その確認がトランザクションコミットまで遅延されることはありません。 SQL 標準によると、デフォルトの動作は遅延チェックにするべきです。 つまり、SQL ステートメント全体が処理されたあとにはじめて、制約がチェックされます。 これは、外部キーを使用して自己参照する行を削除できないことを意味します。-
InnoDB
を含むストレージエンジンは、参照整合性制約定義で使用されるMATCH
句を認識または適用しません。 明示的なMATCH
句を使用しても効果はなく、ON DELETE
句およびON UPDATE
句は無視されます。MATCH
の指定は避けてください。SQL 標準の
MATCH
句は、参照テーブルの主キーと比較する際にコンポジット (複数カラム) 外部キーのNULL
値がどのように処理されるかを制御します。 MySQL は、基本的にMATCH SIMPLE
で定義されたセマンティクスを実装します。これにより、外部キーをすべてまたは一部NULL
にすることができます。 その場合、このような外部キーを含む (子テーブル) 行は、参照される (親) テーブルのどの行とも一致しなくても挿入できます。 (トリガーを使用して他のセマンティクスを実装できます。) -
MySQL では、パフォーマンス上の理由から、参照カラムをインデックス付けする必要があります。 ただし、MySQL では、参照されるカラムが
UNIQUE
であるか、NOT NULL
として宣言されている必要はありません。UNIQUE
でないキーを参照するFOREIGN KEY
制約は、標準 SQL ではなくInnoDB
の拡張機能です。 一方、NDB
ストレージエンジンでは、外部キーとして参照される任意のカラムに明示的な一意キー (または主キー) が必要です。一意でないキーまたは
NULL
値を含むキーへの外部キー参照の処理は、UPDATE
やDELETE CASCADE
などの操作に対して適切に定義されていません。UNIQUE
(PRIMARY
を含む) およびNOT NULL
キーのみを参照する外部キーを使用することをお勧めします。 MySQL は、参照がカラム指定の一部として定義されている「「インライン
REFERENCES
仕様」」 (SQL 標準で定義されているもの) を解析しますが、無視します。 MySQL は、個別のFOREIGN KEY
指定の一部として指定されている場合にのみREFERENCES
句を受け入れます。 外部キーをサポートしていない (MyISAM
などの) ストレージエンジンの場合、MySQL Server は、外部キーの指定を解析して無視します。
外部キー制約の詳細は、セクション13.1.20.5「FOREIGN KEY の制約」 を参照してください。