VillageSQL is a drop-in replacement for MySQL with extensions.
All examples on this page work on VillageSQL. Install Now →
外部キーの定義
fk_orders_customer)は省略可能ですが、付ける価値があります。エラーメッセージに表示され、ALTER TABLE 操作が容易になります。
外部キーには InnoDB が必要です。MyISAM は外部キーを黙って無視します。
参照アクション
ON DELETE 句と ON UPDATE 句は、参照先の親行が削除または更新されたときに子行に何が起こるかを定義します。
SET DEFAULT は SQL 標準の一部です。InnoDB はこの構文を問題なく受け入れますが、実装していません。実行時には RESTRICT とまったく同じように動作します(ERROR 1451)。使用しないでください。名前が示すのとは逆のことを黙って行います。
DELETE 時の CASCADE は便利ですが危険です。顧客を削除すると、その顧客のすべての注文が自動的に削除されます。エラーも警告もありません。依存する行が親なしでは本当に意味を持たない場合(たとえば、注文のない注文明細行)にのみ使用してください。
RESTRICT はより安全なデフォルトです。アプリケーションに削除を明示的に処理させるため、意図しないデータ損失を防ぎます。
必須のインデックス
MySQL は外部キー列にインデックスを必要とします。インデックスが存在しない場合、InnoDB が自動的に作成します。外部キーチェックの確認と無効化
一括データロードの間、外部キーチェックはすべての挿入を遅くします。一時的に無効にします。既存の外部キーの表示
よくある質問
外部キーはパフォーマンスを低下させますか?
子テーブルへのすべての INSERT は、親テーブルに対するチェック(インデックス検索)を引き起こします。親テーブルからのすべての DELETE は、子行の有無のチェックを引き起こします。高スループットのテーブルでは、これらのチェックが積み重なります。書き込みスループットを優先するチームは、代わりにアプリケーション層で参照整合性を強制することがよくあります。どちらの選択も常に正しいわけではありません。トレードオフは、データベースレベルの安全性と書き込みパフォーマンスの間にあります。既存のテーブルに外部キーを追加できますか?
はい、ALTER TABLE で追加できます。
orders の既存の行に、customers に存在しない customer_id 値がある場合、ALTER TABLE は失敗します。先にデータを修正してください。
MySQL が外部キーのインデックスを自動的に作成するのはなぜですか?
InnoDB は、親行が削除または更新されたときに子行を素早くチェックする必要があります。FK 列にインデックスがなければ、そのチェックには子テーブルのフルテーブルスキャンが必要です。自動作成されるインデックスがこれを防ぎます。先に(意味のある名前で)独自のインデックスを作成しておけば、InnoDB は 2 つ目を作成せずにそれを使用します。トラブルシューティング
関連項目
- MySQL における正規化 — 外部キーが強制するスキーマ設計
- MySQL のトランザクション — 外部キーのチェックはトランザクション内で行われます
- MySQL の JOIN のパフォーマンスとよくある間違い — 外部キーが定義する関係へのインデックス作成
- MySQL のソフトデリート — カスケードがソフトデリートを無視する理由
- MySQL の INNER JOIN — これらの関係をまたいで問い合わせるチュートリアルのレッスン
- MySQL の結合の仕組み — そもそもデータが複数のテーブルに分かれている理由