1

与えられたスキーマ

PERSON {名前、配偶者}

ここで、PERSON.spouse は PERSON.name の外部キーです。未婚の場合や情報がない場合は NULL が必要になります。

ヌルに反対する議論を続けますが、この場合、どのようにヌルを回避しますか?

代替スキーマがあります

人物 {名前}
配偶者 { name1, name2 }

ここで、SPOUSE.name* は PERSON への FK です。ここで私が目にする問題は、配偶者が 1 人だけであることを保証する方法がないことです (考えられるすべての UNIQUE 制約があっても、配偶者が 2 人いる可能性があります)。

部品表スタイルの関係でヌルを除外する最良の方法は何ですか?

4

7 に答える 7

2

このタイプの関係に NULL や重複を適用しないと、スキーマ定義が必要以上に複雑になると思います。null を許可したとしても、1 人が複数の配偶者を持っていたり、記録が矛盾していたり​​する可能性があります。

PERSON { A, B }
PERSON { B, C }
PERSON { C, NULL }

たとえば、あるタイプの人だけが配偶者を持つことができるようにするために、性別 (または同性結婚の「配偶者番号」?) などのデータをさらに導入する必要があります。他の人の配偶者は、最初の人の記録によって決定されます。例えば:

PERSON { A, FEMALE, B }
PERSON { B, MALE, NULL }
PERSON { C, FEMALE, NULL }

...そのため、FEMALE である PERSON のみが null 以外の SPOUSE を持つことができます。

しかし、私見ですが、これは複雑すぎて、NULL を使用しても直感的ではありません。NULL がないと、さらに悪化します。文字通り選択の余地がない場合を除き、このようなスキーマ制限を作成することは避けます。

于 2008-12-15T15:56:03.707 に答える
1

もちろん、誰かが同じ名前を持つ可能性があるため、最初に自動インクリメント ID を使用します。しかし、私はあなたがそれをするつもりであり、それについて口論しないと思います. しかし、NULL に対する議論は正確にはどのように進むのでしょうか? 私は NULL に問題はなく、それがこの問題の適切な解決策だと思います。

于 2008-12-15T15:42:02.080 に答える
1

誰もこれをまだ指摘していない理由はわかりませんが、実際には、質問とほぼ同じモデルを使用して、配偶者が1人だけであることを確認するのは非常に簡単です.

名前を主キーとして使用することは当面無視します (名前は変更される可能性があり、重複はかなり一般的であるため、適切な選択ではありません)。彼らがいつ配偶者だったのかを知るために、何らかの発効日を追加することをお勧めします.Joe Celkoは時間モデリングについていくつかの良いものを書いていますが、私はそれがどの本にあったか覚えていません. そうしないと、私が離婚して再婚した場合、別のときに別の配偶者がいたことを失うことになります-それはあなたにとって重要ではないかもしれません.

また、名前を first_name、middle_name、last_name、prefix、suffix などに分割することもできます。

それらの注意点を考えると...

CREATE TABLE People
(
     person_name     VARCHAR(100),
     CONSTRAINT PK_People PRIMARY KEY (person_name)
)
GO
CREATE TABLE Spouses
(
     person_name     VARCHAR(100),
     spouse_name     VARCHAR(100),
     CONSTRAINT PK_Spouses PRIMARY KEY (person_name),
     CONSTRAINT FK_Spouses_People FOREIGN KEY (person_name) REFERENCES People (person_name)
)
GO

People テーブルにも配偶者を表示させたい場合は、そのための FK を追加することもできます。ただし、その時点では、双方向リンクを扱っているため、もう少し複雑になります。

于 2008-12-15T17:12:37.357 に答える
0

よし、Auto-ID を使用してから、Check Constraint を使用する。「Name1」列 (int ID のみ) は ODD 番号付き ID のみを持つように強制され、Name2 は EVEN のみを持つようになります。

次に、Column1 と Column2 の一意の制約を作成します。

于 2008-12-15T16:00:31.637 に答える
0

まず、名前以外のキー、おそらく int シードを使用します。ただし、誰かが複数の配偶者を持つことを防ぐには、配偶者テーブルの親 (name1) に一意のインデックスを追加するだけです。これにより、同じ name1 を 2 回挿入することがなくなります。

于 2008-12-15T15:52:05.820 に答える
0

トリガーを使用して制約を適用できます。PostgreSQL には制約トリガーがあります。これは、トランザクションの適切な時期まで制約の評価を延期するための特に優れた方法です。

データベース管理におけるファビアン・パスカルの実用的な問題、pp. 66-67 から:

ストアド プロシージャは、トリガーされるかどうかに関係なく、アプリケーション レベルの整合性コードよりも適していますが、宣言型のサポートよりも実質的に劣っており、リスクも高くなります。これは、記述の負担が大きく、エラーが発生しやすく、完全な DBMS 最適化の恩恵を受けられないためです。

...

より優れた宣言整合性サポートを備えた DBMS を選択してください。製品によるそのようなサポートのかなりのギャップを考えると、知識のあるユーザーは少なくとも 、DBMS でサポートされていない制約を正しくエミュレートする立場にあるでしょう。

于 2008-12-15T15:52:17.097 に答える
0

関係を定義するには、person TABLE と別の "Partner_Off" テーブルが必要です。

人物 (ID、名前など);

Partner_Off (id、partner_id、関係);

より複雑な社会的状況に対処するには、おそらくいくつかの日付が必要になるでしょう。さらに、SQL を単純化するには、(fred,wilma,husband) のエントリと (wilma,fred,wife) の一致するエントリが必要です。

于 2008-12-15T16:46:18.970 に答える