多对多和弱实体


16

我有一个不能被另一个定义的实体,并且我希望这个实体参与多对多关系。

示例:一个艺术家有一个专辑(没有艺术家就不能存在该专辑),该专辑也有许多曲目,但是同一首曲目可以存在于许多专辑中。

因此,专辑和曲目之间存在多对多的关系。

如果专辑是一个弱实体,则它的主键是引用艺术家的外键,因此它不能是代表多对多关系的另一个表的外键。

问题是:在SQL中是否可能有这种关系,如果是这样,我该如何表达呢?


不,专辑的主键只是一个使专辑唯一的整数。然后,您可能具有artist_id引用该艺术家的外键。如果要将单个曲目映射到多个专辑,请使用带有的映射表track_id, album_id。易:)
Philᵀᴹ

Answers:


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 2013年

@AlexKuznetsov你是对的,thnx。我也将PK“收缩”到您建议的PK中,(albumID, trackNo)并添加其他“唯一”约束。
ypercubeᵀᴹ

1
记住要允许没有单一名义艺术家的专辑,要么有一个叫“ Various”或类似名字的虚拟艺术家,要么使专辑表的artist列可为空。实际上,每首曲目可能有一位以上的艺术家,因此在那里可能也需要多对多的安排。
David Spillett 2014年

1
@DavidSpillett是的,我们可以这样做,但这会使事情复杂化并偏离所提出的问题。该问题假设/指示每个专辑都有一个歌手。每个曲目不可能有不同的艺术家,每个专辑或曲目也不能有很多艺术家。确实,这并不是对现实世界的很好表示。
ypercubeᵀᴹ

1
@TimAbell我认为这是从工作台一个事故在图表创建(不承认它一样的专辑AlbumTrack连接,由于列中的PK顺序)
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)
) ;

曲目仍被限制为每个专辑最多出现一次。

此外,问题实际上并没有指定曲目是弱实体(仅专辑是)-如果曲目实际上可以独立于艺术家而存在,则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)
) ;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.