多対多および弱いエンティティ


16

別のエンティティに定義されない限り存在できないエンティティがあり、このエンティティを多対多の関係に参加させたい。

例:アーティストにはアルバムがあり(アルバムはアーティストなしでは存在できません)、アルバムにも多くのトラックがありますが、同じトラックが多くのアルバムに存在する可能性があります。

そのため、アルバムとトラックの間には多対多の関係があります。

アルバムが弱いエンティティである場合、その主キーはアーティストを参照する外部キーであるため、多対多の関係を表す別のテーブルへの外部キーにすることはできません。

問題は、SQLでこのような関係を持つことは可能ですか?その場合、どのように表現するのですか?


いいえ、アルバムの主キーは、アルバムを一意にする整数になります。これでartist_id、アーティストを参照する外部キーを取得できます。単一のトラックを複数のアルバムにマッピングする場合は、でマッピングテーブルを使用しtrack_id, album_idます。簡単:)
フィリ

回答:


16

「ダイヤモンド」関係図を使用して、できると思います。

図

CREATE TABLE Artist
( artistID INT NOT NULL
, name VARCHAR(100) NOT NULL
, PRIMARY KEY (artistID)
) ;

CREATE TABLE Album
( artistID INT NOT NULL
, albumID INT NOT NULL
, title VARCHAR(100) NOT NULL
, PRIMARY KEY (artistID, albumID)
, FOREIGN KEY (artistID)
    REFERENCES Artist (artistID)
) ;

CREATE TABLE Track
( artistID INT NOT NULL
, trackID INT NOT NULL
, title VARCHAR(100) NOT NULL
, PRIMARY KEY (artistID, trackID)
, FOREIGN KEY (artistID)
    REFERENCES Artist (artistID)
) ;

CREATE TABLE AlbumTrack
( artistID INT NOT NULL
, albumID INT NOT NULL
, trackID INT NOT NULL
, trackNo INT NOT NULL
, PRIMARY KEY (albumID, trackNo)
, FOREIGN KEY (artistID, albumID)
    REFERENCES Album (artistID, albumID)
, FOREIGN KEY (artistID, trackID)
    REFERENCES Track (artistID, trackID)
, UNIQUE (trackID, albumID)               -- this Unique constraint should be added
                                          -- if no track is allowed twice in an album
) ;

1
+1 AlbumTrackテーブルに次の一意の制約を追加するのは理にかなっていますか:(trackID、albumID)および(albumID、trackNo)
AK

@AlexKuznetsovそうですね、thnx。PKを提案されたものに「縮小」し(albumID, trackNo)、他のUnique制約も追加します。
ypercubeᵀᴹ

1
「Various」などのダミーアーティストを使用するか、アルバムテーブルのアーティスト列をnull可能にすることにより、名目上のアーティストが1人もいないアルバムを許可することを忘れないでください。実際、トラックごとに複数のアーティストがいる可能性があるため、そこにも多対多の配置が必要になる場合があります。
デビッドスピレット14

1
@DavidSpillettはい、それはできますが、事態が複雑になり、質問から逸脱します。この質問は、すべてのアルバムに単一のアーティストがいることを前提としています。トラックごとに異なるアーティストを配置することはできません。アルバムまたはトラックごとに多くのアーティストを配置することもできません。実際、現実の世界をあまりよく表していない。
ypercubeᵀᴹ

1
私は図が作成されたワークベンチ(原因のPK内の列の順序にアルバム-AlbumTrack接続と同じことを認識していない)からの災難だと思う@TimAbell
ypercubeᵀᴹ

2

残念ながらypercubeᵀᴹの答えにコメントするのに十分な担当者がいないので、代わりに別の答えを投稿します-一般的にその答えに同意しますが、AlbumTrack アルバムとトラックの両方が弱いので、主キーと一意の制約は間違っていると思いますエンティティ。たとえば、次の有効なデータは、規定の制約により禁止されます。

 artistID | albumID | trackID | trackNo 
----------+---------+---------+---------
        1 |       1 |       1 |       1
        2 |       1 |       1 |       1

代わりにPRIMARY KEY (artistID, albumID, trackID)、一意の制約を設定および削除して、次のようにします。

CREATE TABLE Artist
( artistID INT NOT NULL
, name VARCHAR(100) NOT NULL
, PRIMARY KEY (artistID)
) ;

CREATE TABLE Album
( artistID INT NOT NULL
, albumID INT NOT NULL
, title VARCHAR(100) NOT NULL
, PRIMARY KEY (artistID, albumID)
, FOREIGN KEY (artistID)
    REFERENCES Artist (artistID)
) ;

CREATE TABLE Track
( artistID INT NOT NULL
, trackID INT NOT NULL
, title VARCHAR(100) NOT NULL
, PRIMARY KEY (artistID, trackID)
, FOREIGN KEY (artistID)
    REFERENCES Artist (artistID)
) ;

CREATE TABLE AlbumTrack
( artistID INT NOT NULL
, albumID INT NOT NULL
, trackID INT NOT NULL
, trackNo INT NOT NULL
, PRIMARY KEY (artistID, albumID, trackID)
, FOREIGN KEY (artistID, albumID)
    REFERENCES Album (artistID, albumID)
, FOREIGN KEY (artistID, trackID)
    REFERENCES Track (artistID, trackID)
) ;

トラックは、アルバムごとに1回しか発生しないように制限されています。

また、質問はトラックが弱いエンティティであることを実際に指定していません(アルバムのみ)-実際にトラックがアーティストとは無関係に存在できる場合TrackAlbumTrackテーブルとテーブルはわずかに異なって定義されます:

CREATE TABLE Track
( trackID INT NOT NULL
, artistID INT
, title VARCHAR(100) NOT NULL
, PRIMARY KEY trackID
, FOREIGN KEY (artistID)
    REFERENCES Artist (artistID)
) ;

CREATE TABLE AlbumTrack
( artistID INT NOT NULL
, albumID INT NOT NULL
, trackID INT NOT NULL
, trackNo INT NOT NULL
, PRIMARY KEY (artistID, albumID, trackID)
, FOREIGN KEY (artistID, albumID)
    REFERENCES Album (artistID, albumID)
, FOREIGN KEY (trackID)
    REFERENCES Track (trackID)
) ;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.