それは、個人とアドレスの関係が 1 対 0 プラスか、1 対 1 プラスかによって異なります。
プライマリ アドレスが必要な場合は、Persons
テーブル自体に入力します (必須属性であるため)。
一方、アドレスなしで人がスキーマに存在できる場合は、Addresses
テーブル内のすべてのアドレスを同じままにして、テーブルの属性を使用しPersons
てプライマリ (NULL または関連するAddresses
行へのポインター) を選択します。
アドレスのプライマリティをテーブルに保存する場合Addresses
、Bob Smith の 2 つのアドレスが両方ともプライマリであると主張している場合はどうしますか? トリガーでそれを止めることもできますが、スキーマを適切に設計する方がはるかに効率的です。
そして、2 人のルームメイトが同じ住所を共有しているが、1 人はずっとそこに住んでいて、もう 1 人はほとんどの時間をガールフレンドと一緒に過ごしているとしたら、どうなるでしょうか? プライマリティが Addresses テーブルにある場合、個人間で住所行を共有することはできません。
私が理解しようとしているのは、属性を適切なオブジェクトに割り当てる必要があるということです。個人のプライマリ アドレスは、アドレスではなく個人に属します。
最大限の効率と柔軟性を得るには、次のスキーマを使用します。
Persons:
Id primary key
PrimaryAddressId
OtherStuff
Addresses:
Id primary key
OtherStuff
PersonAddresses:
Id primary key
PersonId foreign key on Persons(Id)
AddressId foreign key on Addresses(Id)
Persons.PrimaryAddressId
ハング ポインターである可能性がある小さなデータ整合性の問題があります。許可したいので、主キーの1つへの外部キーにすることはできませんNULL
。つまり、存在しない を指している可能性に対応する必要がありますAddresses.Id
。
Addresses
関連するPersons
行が更新されるように、削除前のトリガーとしてそれを修正するだけです( PrimaryAddressid
NULLに設定)。
または、Addresses
テーブルに "不明" のアドレスを 1 つ持つようにして、すべての行にPersons
少なくとも 1 つのアドレスが含まれるようにすることもできますPrimaryAddressid
。
次に、それを適切な制約付きの関係にして、SQL をいくらか単純化できます。プラグマティズムは、現実の世界ではドグマティズムを打ち負かすことがよくあります:-)