それらは (ほぼ*) 同じです。
外部キー制約を作成すると、適切なインデックスがまだ存在しない場合は、参照テーブルの関連する列にインデックスが自動的に作成されます。
FOREIGN KEY Constraintsのマニュアルページから:
InnoDB では、外部キーのチェックが高速になり、テーブル スキャンが不要になるように、外部キーと参照キーにインデックスが必要です。参照テーブルには、外部キー列が同じ順序で最初の列としてリストされているインデックスが必要です。このようなインデックスが存在しない場合は、参照テーブルに自動的に作成されます。外部キー制約を適用するために使用できる別のインデックスを作成すると、このインデックスは後でサイレントに削除される可能性があります。index_name が指定されている場合は、前述のように使用されます。
鉱山を強調します。
(*)微妙な違いがあるのでほぼ同じと言っています。
インデックスの名前
最初のバージョンでは、インデックスに明示的な名前を付けましたが、2 番目のバージョンでは、インデックスの名前は制約の名前と同じです (指定されている場合)。
SHOW INDEX
両方の場合の出力を比較します。
バージョン 1:
Table Non_unique Key_name Seq_in_index Column_name ...
タイトル 1 注文番号 1 注文番号 ...
バージョン 2:
Table Non_unique Key_name Seq_in_index Column_name ...
タイトル 1 order_number_fk 1 order_number ...
ご覧のとおり、ここでの唯一の違いはインデックスの名前です。
サイレントドロップ
もう 1 つの微妙な違いは、2 番目のケースでは、ドキュメントに記載されているように、新しいインデックスが追加されると、自動的に作成されたインデックスがサイレントに削除される可能性があることです。
外部キー制約を適用するために使用できる別のインデックスを作成すると、このインデックスは後でサイレントに削除される可能性があります。
これは、たとえば、後で複数列のインデックスを作成する場合、次のことを意味します(order_number, title)
。
CREATE INDEX ix_order_number_title ON title (order_number, title);
次に、SHOW INDEX
再度実行します。
バージョン 1:
Table Non_unique Key_name Seq_in_index Column_name ...
タイトル 1 注文番号 1 注文番号 ...
タイトル 1 ix_order_number_title 1 order_number ...
タイトル 1 ix_order_number_title 2 タイトル ...
バージョン 2:
Table Non_unique Key_name Seq_in_index Column_name ...
タイトル 1 ix_order_number_title 1 order_number ...
タイトル 1 ix_order_number_title 2 タイトル ...
最初のバージョンには 2 つのインデックスがありますが、2 番目のバージョンには 1 つしかないことがわかります。2 番目のバージョンでは、複数列のインデックスを追加すると、外部キー制約によって自動作成されたインデックスが再び自動的に削除されました。通常、これは深刻な問題ではありません。これは、新しいインデックスによって元のインデックスがほとんど冗長になるためです。
どちらを使用しますか?
通常、外部キー制約の参照テーブルに明示的にインデックスを作成することについて心配する必要はありません。
ただし、次の場合は明示的にインデックスを作成することをお勧めします。
- 制約の名前とは異なる名前を付けたい場合、または
- 他のインデックスが追加されたときに、インデックスが黙って消えるのは望ましくありません。