7

最近、さまざまなプロジェクトでこのシナリオに何度も遭遇しました。以下は、文字でラベル付けされた 4 つのテーブルの図です。

     A
  1 / \ 1
   /   \
* /     \ *
 B       C
1 \     / 1
   \   /
  * \ / *
     D

このシナリオでは、BtoACtoのキーAが特定の と一致しない場合、データの一貫性が失われる可能性がありますD

A特定の (構成された) 例として、 is CompanyBis EmployeeCis Project、およびDisを想像してくださいWorkItem。この場合、プロジェクトを所有する会社でさえ働いていない人に割り当てられると主張する作業項目が作成されるのを止めるものは何もありません。

私は主に興味がありますが、この問題に対する設計上の解決策はありますか? これが重要な実際のアプリケーションでは、トリガーまたはその他の保護手段を使用できることを私は知っています。このような不一致を不可能にするためにテーブルを変更する方法は見つかりませんでした。方法はありますか?

Cからへのように、接続の 1 つを切断するだけでAはうまくいかないことに注意しDCくださいA

4

1 に答える 1

7

下流のテーブルには複合キー(つまり、複数のフィールドを含むキー) を使用します。次に、D では、1 つのフィールドだけを使用して A のキーを保持できます。

[編集: D の 2 番目の FK で愚かなコピー & ペースト エラーを修正!]

CREATE TABLE A (
  A_ID INTEGER PRIMARY KEY
  -- Any other fields you want...
);

CREATE TABLE B (
  A_ID INTEGER REFERENCES A.A_ID,
  B_ID INTEGER,
  -- Any other fields you want...
  PRIMARY KEY (A_ID, B_ID)
);

CREATE TABLE C (
  A_ID INTEGER REFERENCES A.A_ID,
  C_ID INTEGER,
  -- Any other fields you want...
  PRIMARY KEY (A_ID, C_ID)
);

CREATE TABLE D (
  A_ID INTEGER,    -- This field forms part of the FK for BOTH B and C
  B_ID INTEGER,
  C_ID INTEGER,
  D_ID INTEGER,
  -- Any other fields you want...
  PRIMARY KEY (A_ID, B_ID, C_ID, D_ID),
  FOREIGN KEY (A_ID, B_ID) REFERENCES B (A_ID, B_ID),
  FOREIGN KEY (A_ID, C_ID) REFERENCES C (A_ID, C_ID)
);

私は上記の SQL をテストしていませんが、うまくいけばアイデアが得られるでしょう。D は A に戻る 3 番目の FK 制約を必要としないことに注意してください。これは、他の FK によって既に暗示されているためです (実際には、それぞれの FK によって個別に暗示されています)。

参照整合性チェックは常にトリガーよりも優れています。少なくとも PostgreSQL ではそうです。すべての RDBMS でそれが当てはまると思います。

于 2013-10-24T15:52:34.460 に答える