Nhiều đến nhiều và các thực thể yếu


16

Tôi có một thực thể không thể tồn tại mà không được xác định bởi người khác và tôi muốn thực thể này tham gia vào mối quan hệ nhiều-nhiều.

Ví dụ: Một nghệ sĩ có một album (album không thể tồn tại mà không có nghệ sĩ), album cũng có nhiều bản nhạc, nhưng cùng một bản nhạc có thể tồn tại trong nhiều album.

Vì vậy, chúng tôi có mối quan hệ nhiều-nhiều giữa album và các bài hát.

Nếu album là một thực thể yếu, thì khóa chính của nó là khóa ngoại tham chiếu đến nghệ sĩ, do đó, nó không thể là khóa ngoại đối với một bảng khác thể hiện mối quan hệ nhiều-nhiều.

Câu hỏi là: có thể có loại mối quan hệ này trong SQL không, và nếu vậy, làm thế nào để tôi thể hiện nó?


Không, khóa chính của album sẽ chỉ là một số nguyên làm cho album trở nên độc đáo. Sau đó bạn có thể có một artist_idkhóa ngoại tham chiếu đến nghệ sĩ. Nếu bạn muốn một bản nhạc duy nhất được ánh xạ tới nhiều album thì hãy sử dụng bảng ánh xạ với track_id, album_id. Dễ dàng :)
Philᵀᴹ

Câu trả lời:


16

Tôi nghĩ bạn có thể, sử dụng sơ đồ mối quan hệ "kim cương":

biểu đồ

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 Sẽ có ý nghĩa với bạn khi thêm các ràng buộc duy nhất sau đây vào bảng AlbumTrack: (trackID, albumID) và (albumID, trackNo)?
AK

@AlexKuznetsov Bạn nói đúng, thnx. Tôi cũng sẽ "thu nhỏ" PK vào đề xuất của bạn (albumID, trackNo)và thêm các ràng buộc Duy nhất khác.
ypercubeᵀᴹ

1
Hãy nhớ cho phép các album không có nghệ sĩ danh nghĩa duy nhất, bằng cách có một nghệ sĩ giả tên là "Khác nhau" hoặc tương tự hoặc bằng cách làm cho cột nghệ sĩ của bảng album không thể bị xóa. Trên thực tế, bạn có thể có nhiều hơn một nghệ sĩ trên mỗi bài hát, vì vậy bạn cũng có thể cần một sự sắp xếp nhiều-nhiều ở đó.
David Spillett

1
@DavidSpillett Vâng, chúng tôi có thể làm điều đó nhưng nó sẽ làm phức tạp mọi thứ và đi chệch hướng câu hỏi. Câu hỏi giả định / ra lệnh rằng mỗi album có một nghệ sĩ duy nhất. Không thể có các nghệ sĩ khác nhau trên mỗi bản nhạc, không có nhiều nghệ sĩ cho mỗi album hoặc bản nhạc. Đó thực sự không phải là một đại diện tốt của thế giới thực.
ypercubeᵀᴹ

1
@TimAbell Tôi nghĩ rằng đó là một sự cố từ Workbench nơi các sơ đồ được tạo ra (không nhận ra nó giống như kết nối Album-AlbumTrack do thứ tự các cột trong PK)
ypercubeᵀᴹ

2

Thật không may, tôi không có đủ đại diện để nhận xét về câu trả lời của ypercubeᵀᴹ , vì vậy tôi sẽ đăng một câu trả lời thay thế - tôi đồng ý với câu trả lời đó nói chung nhưng nghĩ rằng khóa chính và các điều kiện độc đáo trên AlbumTrack là không chính xác vì các album và bài hát đều yếu thực thể. Ví dụ: dữ liệu hợp lệ sau đây, với các ràng buộc được quy định, sẽ không được phép:

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

Thay vào đó tôi sẽ thiết lập PRIMARY KEY (artistID, albumID, trackID)và loại bỏ các ràng buộc duy nhất, dẫn đến:

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)
) ;

Các bản nhạc vẫn bị hạn chế xuất hiện nhiều nhất một lần cho mỗi album.

Ngoài ra, câu hỏi không thực sự xác định rằng các bản nhạc là các thực thể yếu (chỉ có album đó) - nếu trên thực tế các bản nhạc có thể tồn tại độc lập với các nghệ sĩ, thì các bảng TrackAlbumTrackđược định nghĩa hơi khác nhau:

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)
) ;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.