外部キーは、リレーショナルデータベースで関係を作成するための不可欠な部分です。その理由と作成方法は次のとおりです。
そのため、主キーがテーブルの一意の識別子を提供することを確立しました。ただし、「キー」タイプは主キーだけではありません。データベースには外部キーを含めることもできます。
外部キーとは何ですか?
外部キー 別のテーブルの行を一意に識別する1つのテーブルの列(または列のコレクション)です。これにより、2つのテーブル間の関係が定義されます。
外部キーを使用すると、テーブル間で関連データを相互参照できます。これは、列に別のテーブルで表されるデータが含まれている場合に便利です。
例
これが私たちの FruitShop の図です Fruit 間の関係を示すデータベース テーブルと ユニット テーブル。
2つのテーブルを結ぶ黒い線は、外部キーを示します。 UnitId Fruit のフィールド テーブルは UnitId への外部キーです ユニット のフィールド テーブル。したがって、 Fruit.UnitId に挿入する値 Units.UnitId の値に対応している必要があります 。これにより、 Fruit.UnitId が有効になります そのレコードの他の列(つまり、対応する UnitId を持つレコード)のデータを参照します 。
データ
つまり、 Fruit テーブルには次のようなレコードが含まれています:
FruitId | FruitName | 在庫 | UnitId | DateEntered | DateUpdated |
---|---|---|---|---|---|
1 | アップル | 10 | 3 | 2012-11-27 12:42:10 | 2012-11-27 12:42:10 |
そして私たちの ユニット テーブルには次のレコードが含まれています:
UnitId | UnitName | DateEntered | DateUpdated |
---|---|---|---|
1 | ピース | 2011-12-30 12:46:15 | 2011-12-30 12:46:15 |
2 | 束 | 2011-12-30 12:46:15 | 2011-12-30 12:46:15 |
3 | キログラム | 2011-12-30 12:46:15 | 2011-12-30 12:46:15 |
4 | コンテナ | 2011-12-30 12:46:15 | 2011-12-30 12:46:15 |
5 | ポンド | 2011-12-30 12:46:15 | 2011-12-30 12:46:15 |
6 | オンス | 2011-12-30 12:46:15 | 2011-12-30 12:46:15 |
Fruit.UnitId
フィールドに3
が含まれています 。次に、
ユニット
を見てください。 3
を含むレコードのテーブル
UnitId
内 分野。このレコードが
キログラム
を表していることがわかります 。したがって、リンゴはキログラムで測定されることがわかりました。
この方法でデータベースを設定することの良い点は、そのユニットを使用するすべてのレコードに対して「キログラム」を繰り返す必要がないことです。重複を減らすことは、リレーショナルデータベース管理システムの重要な利点です。
Fruit でできるだけ多くのレコードを見る テーブルは同じユニット名(「キログラム」、「コンテナ」、「バンチ」など)を共有するため、データベースに重複を追加する前に慎重に検討する必要があります。外部キーの関係を使用せずに、ユニット名を Fruit に直接書き込むことができます。 テーブル(そしておそらく列を「Unit」、「UnitType」または「UnitName」と呼びます)。そうすると、ユニット名列に同じ値を共有する多くのレコードができあがります。多くの記録に対して「キログラム」が何度も繰り返されるのを目にするでしょう。また、「バンチ」が繰り返されたり、その他の一般的なユニットタイプが表示されたりします。
これを行うことは必ずしも「間違っている」わけではありませんが、一般に、これらのユニット名ごとに1つのレコードを個別のテーブルに格納し、 UnitId を介してそのテーブルを参照する方が効率的です。 桁。これを行うことは、 Fruits で作成されたすべてのレコードに対してこれらのユニット名を何度も繰り返すよりも効率的です。 テーブル。また、ユニット名を更新する場合(たとえば、「キログラム」を「キログラム」に変更する場合)も簡単になります。ユニット名を更新しても、 Fruit には影響しません。 UnitId のためのテーブル 同じままになります。さらに、データベースに一貫性のないデータが表示されるのを防ぐのにも役立ちます。
外部キー制約
外部キー制約は、外部キーデータの一貫性を維持するのに役立つデータベースオブジェクトです。参照整合性を維持するために外部キー制約を作成します。外部キー制約を作成することにより、MySQLにデータに対して特定のルールを適用するように指示します。データが挿入、削除、または更新されると、MySQLはデータがテーブル間に作成した外部キーに準拠していることを確認します。そうでない場合は、データの書き込み/上書き/削除が防止されるため、参照整合性が維持されます。
たとえば、ユーザーがUnitId値を Fruit.UnitId に入力しようとした場合 列ですが、 Units.UnitId に対応するレコードがありません 列の場合、MySQLはユーザーがその値を入力できないようにします。
2つのテーブルを作成するときに、 Fruit に外部キー制約を追加しました。 テーブル。制約を作成するために使用したコードは次のとおりです。
CONSTRAINT fkFruitUnits FOREIGN KEY (UnitId) REFERENCES Units (UnitId) ON DELETE RESTRICT ON UPDATE CASCADE
左側の SCHEMAS のノードを展開すると タブで、作成した外部キー(および主キー)を確認できます:
外部キー制約に準拠していないデータを挿入しようとすると、エラーが発生するはずです。
たとえば、レコードを Fruit に挿入しようとすると UnitId を使用したテーブル ユニット に存在しない値 テーブル、次のエラーが表示されます:
これは、5
の値を挿入しようとしているために発生します
UnitId
に
Units.UnitId
に対応する値がない場合の列 フィールド。
これを成功させるには、
ユニット
にレコードがあることを確認する必要があります
UnitId
を含むテーブル 5
の 。
外部キーが機能していませんか?
外部キーが機能していないように見える場合があります。たとえば、データの挿入を妨げる外部キーがある場合でも、データをテーブルに正常に挿入できます。
この状況で確認できることがいくつかあります。
-
ON DELETE
が追加されていることを確認してください およびON UPDATE
コード内の句。たとえば、ON DELETE RESTRICT ON UPDATE CASCADE
。このコードを配置するタイミングについては、CREATETABLEの例を参照してください。 - テーブルがInnoDBであることを確認します 。これを行うには、
ENGINE=InnoDB
を追加しますCREATE TABLE
の最後まで ステートメント(テーブルを作成したときの私の例を参照してください)。一部のエンジン( MyISAM など) )外部キー制約をサポートしていませんが、外部キー制約を作成しようとしたときに、これに関する警告は表示されません。デフォルトのエンジンがInnoDBでない場合 そうすると、外部キーがサポートされなくなる可能性があります。 - MySQLが実際に外部キーをチェックしていることを確認します。これを行うには、次のコードを実行します:
SET FOREIGN_KEY_CHECKS=1
。
外部キーチェックを無効にする
外部キーの制約が不必要に制限される場合があります—データのロードの作業を大幅に妨げるまでです。たとえば、データベースを作成したばかりで、初期データをロードする必要がある場合です。または、大量のテーブルを削除してデータをリロードする必要がある場合。
データを正しい順序でロードしないと、データが間違った順序でロードされるために外部キーエラーが発生し続ける可能性があります(つまり、親テーブルが子テーブルをロードする前に子テーブルをロードしようとしています)データが読み込まれます。
これは、読み込み中の場合の問題だけではありません。 データ。そもそもデータベースを作成するときにも、この問題が発生する可能性があります。テーブルを正しい順序で作成しないと、外部キーの制約が原因でエラーが発生する可能性があります。
正しい親子の順序がわからない場合は、データベースを作成したりデータをロードしたりするための正しい順序を確立するのに、多くの時間と労力がかかる可能性があります。このような場合は、MySQLに一時的に外部キーをチェックしないように指示した方がよい場合があります。
次のコードを使用して、外部キーチェックを無効にできます。
FOREIGN_KEY_CHECKS=0
再度有効にするには、次のようにします。
FOREIGN_KEY_CHECKS=1