0

私の場合を例に説明します。

次のテーブルがあります: personsplacespictures。人物も場所も写真が多い。参照整合性を維持しながらデータベース スキームでこれを表現する最良の方法は何ですか?

  1. 考えられる関連ごとに列を追加することもできますが、これにより、他にも写真があるものがある場合に多くの空のフィールドが作成されます。
  2. personspicturesplacesとの間に関連テーブルを作成できましpicturesた。しかし、外部キーは関連付けテーブルにあり、場所などが削除されたときにピクチャを削除することを強制することはできません。

現時点では、2 番目のアプローチに傾いていますが、好きではありません。

4

2 に答える 2

2

必要なすべてのボックスにチェックマークを付ける万能のソリューションはありません。しかし、私が以前に見たのは

3) 関係を共有する項目のベース テーブルを導入します。

CREATE TABLE Entities (
    EntityID int not null primary key,
    EntityType varchar(10) not null,
    constraint CK_EntityTypes CHECK (EntityType in ('Person','Place')),
    constraint UQ_Entities_WithTypes UNIQUE (EntityID,EntityType)
)

そして、PeopleテーブルPlacesを構築します。

CREATE TABLE People (
    PersonID int not null PRIMARY KEY,
    EntityType AS CAST('Person' as varchar(10)) persisted,
    ...Other columns...
    constraint FK_People_Entities FOREIGN KEY (PersonID,EntityType) references Entities (EntityID,EntityType)
)

CREATE TABLE Places (
    PlaceID int not null PRIMARY KEY,
    EntityType AS CAST('Place' as varchar(10)) persisted,
    ...Other columns...
    constraint FK_Places_Entities FOREIGN KEY (PlaceID,EntityType) references Entities (EntityID,EntityType)
)

Entities場所について考えるとき、正確に正しいかどうかはわかりません-より良い名前があなたに提案されるかもしれません)。

Pictures参照するだけで済みますEntityID


それ以外の場合、1 と 2 の間で選択する必要がある場合は、通常は 1 をお勧めします。関連する「型」の数が大きくならない限り、それでもPicturesテーブルが広くなりすぎることはありません。必要に応じて、少なくとも通常の FK メカニズムを使用してカスケードを強制します。


4)Pictures現時点で非常にむき出しのテーブルである場合は、pictures テーブルが1 つ必要か、タイプごとに 1 つ必要かを問い合わせます。人物の写真と場所の写真が一緒にクエリされることがよくありますか (たとえそうであったとしても、UNION ALLベース クエリによって、別々のテーブルを使用しているという事実が隠される可能性があります)。

于 2013-01-28T14:28:50.200 に答える
1

3つの方法があると思います。1つは、各エンティティを画像にマッピングする個別のテーブルを用意することです。何かのようなもの:

create table PersonPictures . . .
    PersonId int not null,
    PictureId int not null

. . .

create table PlacesPictures . . .
    PlaceId int not null,
    PictureId int not null

これは、人物と場所が別々のエンティティであり、写真に関する他の情報(人物が何を着ていたか、場所の視点など)が異なる場合に機能します。

人と場所が実際には写真の単なる属性である場合は、次のようにすることができます。

create table AttributesPictures . . .
    PictureId int not null,
    AttributeType varchar(255),  -- 'Person', 'Place'
    PersonId int,
    PlaceId int

この場合、明確に定義された値のみを取得するように制約を設定できAttributeTypeます(または、別のルックアップテーブルで属性IDを使用します)。また、外部キーの制約:AttributeType ='Person'の場合、PersonIdはnullではなく、PlaceIdはnullです。

写真に最大で1人の人物と1つの場所が含まれている場合は、これらのIDを写真レコード自体に保存できます。この特殊なケースでは非常に便利です。

どのアプローチを採用するかは、アプリケーションの要件によってさらに左右されるはずです。どのアプローチでも、外部キー関係とカスケード削除を使用して、レコードが適切に削除されるようにすることができます。または、トリガーを使用してリレーショナル整合性を適用することもできます(ただし、これは私のお気に入りのソリューションではありません)。

于 2013-01-28T14:20:26.223 に答える