我有一个不能被另一个定义的实体,并且我希望这个实体参与多对多关系。
示例:一个艺术家有一个专辑(没有艺术家就不能存在该专辑),该专辑也有许多曲目,但是同一首曲目可以存在于许多专辑中。
因此,专辑和曲目之间存在多对多的关系。
如果专辑是一个弱实体,则它的主键是引用艺术家的外键,因此它不能是代表多对多关系的另一个表的外键。
问题是:在SQL中是否可能有这种关系,如果是这样,我该如何表达呢?
我有一个不能被另一个定义的实体,并且我希望这个实体参与多对多关系。
示例:一个艺术家有一个专辑(没有艺术家就不能存在该专辑),该专辑也有许多曲目,但是同一首曲目可以存在于许多专辑中。
因此,专辑和曲目之间存在多对多的关系。
如果专辑是一个弱实体,则它的主键是引用艺术家的外键,因此它不能是代表多对多关系的另一个表的外键。
问题是:在SQL中是否可能有这种关系,如果是这样,我该如何表达呢?
Answers:
我认为您可以使用“钻石”关系图:
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
) ;
(albumID, trackNo)
并添加其他“唯一”约束。
不幸的是,我没有足够的代表对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)
) ;
曲目仍被限制为每个专辑最多出现一次。
此外,问题实际上并没有指定曲目是弱实体(仅专辑是)-如果曲目实际上可以独立于艺术家而存在,则Track
和AlbumTrack
表的定义稍有不同:
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)
) ;
artist_id
引用该艺术家的外键。如果要将单个曲目映射到多个专辑,请使用带有的映射表track_id, album_id
。易:)