関係データベースの外部キー制約と関連付け


目次
記事の目次
  • ディレクトリ
  • 外部キー制約
  • 外部キー関連
  • 外部キーの役割
  • 外部キーの性能問題
  • は外キーを使用しますか?
  • 外鍵を使用する守則
  • インターネットアプリケーションは、外部キーの使用をできるだけ避けるべきです.
  • 業務ロジックにおけるデータベース外鍵のシミュレーション
  • 外部結合の制約
    外部キー制約(Foreign key)は、関係型データベースの中のテーブルの特殊フィールドであり、主キー制約(Primary key)としばしば一緒に使用される.関連関係のある2つのテーブルに対して、関連フィールドのメインキーがあるテーブルがメインテーブル(親テーブル)であり、外部キーがあるテーブルがスレーブテーブル(サブテーブル)である.外部結合制約は、参照の完全性を保証することができる.
    参照の完全性はデータの属性であり、データがこの属性を持っているなら、データ中のすべての参照は合法的であり、関係データベースのコンテキストでは、これは関係データベースに別のテーブルの値を参照する必要があります.
    簡単に言えば、外部キー制約は、表からの関連関係を確立するために使用され、2つのテーブルのデータの接続を確立するために使用され、2つのテーブルのデータの整合性と完全性を制約します.
    NOTE:一つのテーブルには一つ以上の外キーがあります.外キーは空の値でもいいです.空の値でないと、各外キーの値はメインテーブルのメインキーのいずれかの値に等しくなければなりません.
    外部キー関連
    外キー関連とは、Bに外キーb_が存在するということです.f_k,A表のa_でkを参照列とすると、Aはメインテーブル、Bはスレーブテーブルとなります.
  • A、Bがon delete/udateなどの操作に関連すると、Aにある記録の更新または削除は、Bにおける外キーと関連付けられている記録と連動して更新または削除操作を行う.
  • 逆に、Bがどのように変化するかはAに従って変動する必要はなく、AにBが挿入するべきデータ外結合列の値が事前に存在しなければならない.例えば、B.bfkが外キーとしてA.akを参照すると、B.bfk挿入の値はA.akにすでに存在している必要がある.つまり、BがAを参照とする外キーがある場合、Bのこのフィールドの値はAの中の値だけとなります.
  • 外部結合の役割
    外部キーは関係データベースの「参照完全性」をサポートするために使用され、外部キーはデータの整合性と整合性を維持する機構を有し、業務処理に対して非常に良い検証作用を持っている.
    例えば、Table userのColumn user.idがプライマリキーであると仮定し、Table profileのColumn profile.uidがメインキーである.userをはじめとする表、profileを関連表、profile.uidを外部キーとし、user.idを参照とし、削除/更新操作を連動させました.では、
  • は、userからidが1の記録を削除し、profileのuidが1の記録を削除することに連動する.
  • は、米国でidが1であるレコードをIDが2に更新すると、profileではuidが1であるレコードも連動してuidが2に更新される.
  • このようにしてデータの整合性を維持し、データの整合性も保証する.しかもこの作業は、RDBMS内部で実現されるフリップフロップに任せていますので、追加のコードは必要ありません.
    外部キーの性能問題
    外部キーの使用は性能に問題があります.
  • データベースは、外部キーの内部管理を維持する必要がある.
  • 外部キーは、データの一貫性を実現し、すべてデータベースサーバに渡すことと同じです.
  • は、外部キーフィールドの増加、削除、更新操作に関連して、関連する操作をトリガして検査に行く必要があり、リソースを消費しなければならない.
  • 外部キーは、他のテーブルの内部にロックを要求する必要があるため、デッドロックが発生しやすい.
  • 外キーを使いますか?
    外部キーの性能上の問題があるので、外部キーを採用するかどうかは業務の応用シーン、および開発コストを考慮する必要があります.
  • インターネット業界のアプリケーションは、外部キーの使用を推奨しません.このため、データベースサーバは高同時アクセスの性能ボトルネックになりやすく、特にI/O能力に制限され、容易に水平拡張できない.このシーンでは、データ整合性の実現をビジネスロジックにおいて、アプリケーションサーバにこの部分の機能と圧力を負担させるべきです.
  • 従来の業界は、外部キーの使用を考慮することができます.ソフトウェアアプリケーションの人数は限られており、制御可能であり、データベースサーバのデータ量も一般的に大きくないし、アクティブなデータは限られています.このシーンでは、外キーを使うことで開発コストを低減し、RDBMS自身のトリガーにより、本体表と関連テーブルの間のデータの整合性と更新を実現することができる.また、外部キーを使うと、開発者とデータベース設計者(DBA)の分担もできます.DBAはプログラマの仕事量を多く負担できます.
  • 外キーのルールを使う
  • マスタテーブルはすでにデータベースに存在しているか、または現在作成中のテーブルである必要があります.後の場合は、メインテーブルとスレーブテーブルが同じ表であり、このような表を自己参照表と呼び、このような構造を自己参照完全性と呼びます.
  • は、メインテーブルにメインキーを定義しなければならない.
  • 外部キーの列の数は、メインテーブルのメインキーの列の数と同じでなければなりません.
  • 外部キーの列のデータタイプは、メインテーブルのメインキーの中の対応する列のデータタイプと同じでなければなりません.
  • インターネットの応用はできるだけ外国キーの使用を避けるべきです.
    外部キーを使わない理由は簡単です.MySQL、PostgreSQLなどの関係型データベースは水平拡張が難しいですが、無状態のサービスは容易に拡張できます.外部キーなどの特性はデータベースが追加の作業を行う必要がありますが、これらの操作はデータベースの計算リソースを占用しますので、ほとんどの需要を無状態のサービスに移行して、データベースの作業負荷を低減します.したがって、データベースが高合併性能のボトルネックにならないようにします.
    また、カスケード削除の出発点はデータの完全性を保証するためですが、設計関係表間の異なる関係においては、カスケード削除によるデータの大規模削除にも注意が必要です.クライアントがデータベースからauthosテーブルのデータを削除したい場合、authorsとpostsでカスケード削除の挙動を同時に指定したら、データベースは関連のpostsレコードとpostsテーブルに関連するcommentsデータを同時に削除します.
    このようなマルチレベルのカスケード削除挙動は、データ量が小さいデータベースでは問題になりませんが、データ量が大きいデータベースからキーデータを削除すると雪崩を引き起こす可能性があります.レコードの削除は数十倍以上に拡大され、磁気ディスクのランダムI/Oに対して大きなオーバーヘッドをもたらす可能性があります.各テーブル間の関係をよりよく設計し、CASCADE行為を慎重に使うことができれば、データベースにおけるデータの合法性を保証する上で重要な意味があり、この特性を使うと、データベースの中で期限が切れて、合法的でないデータが現れることを避けることができます.
    業務ロジックでデータベースの外部キーをシミュレートする
    アプリケーションでデータベースの外部キーをシミュレートする機能は実は比較的に簡単で、私達は以下のいくつかの基準に従う必要があります.
  • テーブルにデータを挿入したり、テーブル内のデータを修正したりする場合、追加のSELECT文を実行して、その参照データがデータベース内に存在することを確認します.
  • データを削除する前に、追加のSELECT文を実行して、現在のレコードの参照があるかどうかを確認する必要があります.
  • 注意したいのは、一貫性を保証するために、上記の照会と修正文を事務で実行する必要があります.このようにしてこそ、外部キーの機能を完全に模擬することができます.例えば、私たちはpostsテーブルにデータを挿入したり修正したりする場合、必要な処理は比較的簡単であり、限定的なSELECT文を実行して、下記のようなモードで対応する操作を実行すればいいです.
    BEGIN
    SELECT * FROM authors WHERE id = <post.author_id> FOR UPDATE;
    -- INSERT INTO posts ... / UPDATE posts ...
    END
    
    しかし、authorsテーブルのデータを削除するには、authorsデータを参照したすべてのテーブルを調べる必要があります.10のテーブルがauthorsテーブルに向けられている外部キーがある場合、10のテーブルで対応するレコードがあるかどうかを確認する必要があります.このプロセスは相対的に面倒です.しかし、完全性を実現するために必要な代価です.しかし、このようなアナログ外鍵の方法は外部キーを使うよりもはるかに資源を消耗します.また、ネットワークを通じて、より多くのパケットを送信します.
    手動でデータベースのカスケード削除操作を実現してもいいです.もし私達は一つの事務の中で順次にすべてのデータを削除すれば、確かにデータの整合性を保証できます.時間ウィンドウ内のデータが一致しない場合、大きなサイズの削除タスクを複数のサブタスクに分割して実行し、データベースに対する影響のピークを下げることができます.
    DELETE FROM posts WHERE author_id = 1 LIMIT 100;
    DELETE FROM posts WHERE author_id = 1 LIMIT 100;
    ...
    DELETE FROM authors WHERE id = 1;
    
    この方法は、データベースの外部キーのCASCADEに比べて、より大きなオーバーヘッドをもたらすことに注意してください.ただし、データベースの性能に対する瞬時的な影響を低減することができます.