以下は、レコードが同じテーブル内の親レコードを参照できる単純なテーブルです。
CREATE TABLE foo (
id SERIAL PRIMARY KEY,
parent_id INT NULL,
num INT NOT NULL,
txt TEXT NULL,
FOREIGN KEY (parent_id) REFERENCES foo(id)
);
他のフィールド値の1つ(num
)が親レコードと子レコードで同一でなければならないという追加の要件により、複合外部キーがうまくいくはずだと思いました。最後の行を
FOREIGN KEY (parent_id, num) REFERENCES foo(id, num)
そして得たエラー:参照されたテーブル "foo"の指定されたキーに一致する一意の制約はありません。
この制約は簡単に追加できますが、参照されている列の1つ(id
)が既に一意であることが保証されているのに、なぜ必要なのかわかりません。私の見たところ、新しい制約は冗長になります。
これは、DBMSの制限事項です-私が知る限り、それらのすべてにおいて。列を追加するときだけでなく、列を再配置するときも同様です。 _(a1, a2)
_にUNIQUE
制約がある場合、本質的に冗長な_FOREIGN KEY
_に一意の制約がない限り、_(a2, a1)
_ that REFERENCES (a2, a1)
を追加できません。
これを機能として追加することは、それほど難しくありません。
_
(a)
_にUNIQUE
制約がある場合、_(a, b, c, ..., z)
_または_(b,c, ...a, ...z)
_の組み合わせもUNIQUE
が保証されます。
または一般化:
_
(a1, a2, ..., aN)
_にUNIQUE
制約がある場合、_(a1, a2, ..., aN, b1, b2, ..., bM)
_の組み合わせまたは再配置もUNIQUE
が保証されます。
要求されていないか、実装するのに十分高い優先度と見なされていないようです。
機能を実装するためのリクエストは、それぞれのチャネルでいつでも行うことができます。または、DBMSがPostgresのようなオープンソースの場合は、自分で実装することもできます。
一般に、外部キーは(単なる複合ではなく)別のテーブルのある種の一意キーを指している必要があります。そうでない場合、リレーショナルデータの整合性はありません。
(id)に一意のキーがある一方で、(id、num)に一意のキーがないため、これは不満です。したがって、DBに関する限り、(id、num)のペアは一意であることが保証されていません。私たち人間は、それが一意であることを理解できますが、Postgresが「ああ、IDは一意であることがわかるように十分にスマートにするために追加する必要がある多くの追加コードがあると確信しています。 、したがって、id、numも一意である必要があります。
問題を修正するために2つの列に別の一意のインデックスを作成する必要がある場合に、そのコードを追加したとしたら、私は非常に驚きます。
明確にするために、彼らが追加しなければならないコードは、この単純なケースではありません...外部キーが4つ以上の列にあるケースなど、すべてのケースを処理する必要があります。きっとロジックはかなり複雑になります。