MySQL 8.0 リファレンスマニュアル


1.7.2.3 FOREIGN KEY 制約の違い

外部キー制約の 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 値を含むキーへの外部キー参照の処理は、UPDATEDELETE CASCADE などの操作に対して適切に定義されていません。 UNIQUE (PRIMARY を含む) および NOT NULL キーのみを参照する外部キーを使用することをお勧めします。

  • MySQL は、参照がカラム指定の一部として定義されている「インライン REFERENCES 仕様」 (SQL 標準で定義されているもの) を解析しますが、無視します。 MySQL は、個別の FOREIGN KEY 指定の一部として指定されている場合にのみ REFERENCES 句を受け入れます。 外部キーをサポートしていない (MyISAM などの) ストレージエンジンの場合、MySQL Server は、外部キーの指定を解析して無視します。

外部キー制約の詳細は、セクション13.1.20.5「FOREIGN KEY の制約」 を参照してください。


関連キーワード:  制約, 参照, 標準, KEY, InnoDB, UPDATE, FOREIGN, キー, テーブル, 定義