8

これらのテーブルがあるとしましょう:

CREATE TABLE A (
    id SERIAL NOT NULL PRIMARY KEY
);
CREATE TABLE B (
    id SERIAL NOT NULL PRIMARY KEY
);
CREATE TABLE Parent (
    id SERIAL NOT NULL PRIMARY KEY,
    aId INTEGER NOT NULL REFERENCES A (id),
    bId INTEGER NOT NULL REFERENCES B (id),
    UNIQUE(aId, bId)
);
CREATE TABLE Child (
    parentId INTEGER NOT NULL REFERENCES Parent (id),
    createdOn TIMESTAMP NOT NULL
);

Childすべての行に対して、最大で 1 つの値をChild参照するように一意の制約を作成することは可能ですか? 別の言い方をすれば、上記のテーブルの結合に重複がないように一意の制約を作成できますか? 私が見つけたすべてのデータベースの文法は、制約ごとに 1 つのテーブルに結び付けられているように見えますが、それは私の想像力の欠如かもしれません。(もちろん、 onを含めるための非正規化は 1 つの解決策です。)ParentaIdaIdaIdChild

4

2 に答える 2

4

以下を試すことができます。Parentで冗長な UNIQUE 制約を作成する必要があります(id, aId)(SQL はかなりばかげていますよね?!)。

CREATE TABLE Child
(parentId INTEGER NOT NULL,
 aId INTEGER NOT NULL UNIQUE,
FOREIGN KEY (parentId,aId) REFERENCES Parent (id,aId),
createdOn TIMESTAMP NOT NULL);

おそらく、はるかに優れた解決策は、子テーブルからparentIdを完全に削除し、bId代わりに追加して、に基づいて親テーブルを参照すること(aId, bId)です。

CREATE TABLE Child
(aId INTEGER NOT NULL UNIQUE,
 bId INTEGER NOT NULL,
FOREIGN KEY (aId,bId) REFERENCES Parent (aId,bId),
createdOn TIMESTAMP NOT NULL);

それができない理由はありますか?

于 2011-06-08T19:23:23.907 に答える
1

これを行う適切な方法は、Childテーブルを完全に廃止し、制約なしでテーブルにcreatedOn列を配置することです。あなたが言っているのは、1 つのエントリが 0 個または 1 個 (ただしそれ以上) の値を持つことができるということだけです。そのための別のテーブルは必要ありません。他の方法で行うのは簡単ではない、または明白ではないという事実は、私の主張を部分的に証明しています. ;-) SQL は通常、そのように機能します。ParentNOT NULLParentcreatedOn

于 2011-06-09T08:25:43.607 に答える