Banyak ke Banyak dan Entitas Lemah

16

Saya memiliki entitas yang tidak dapat eksis tanpa ditentukan oleh entitas lain, dan saya ingin entitas ini berpartisipasi dalam hubungan banyak ke banyak.

Contoh: Artis memiliki album (album tidak dapat ada tanpa artis), album ini juga memiliki banyak trek, tetapi trek yang sama dapat ada di banyak album.

Jadi kami memiliki hubungan banyak-ke-banyak antara album dan trek.

Jika album adalah entitas yang lemah, maka kunci utamanya adalah kunci asing yang merujuk artis tersebut, sehingga tidak dapat menjadi kunci asing ke tabel lain yang mewakili hubungan banyak ke banyak.

Pertanyaannya adalah: apakah mungkin untuk memiliki hubungan semacam ini dalam SQL, dan jika demikian, bagaimana cara saya mengungkapkannya?

Raiden Freeman
sumber
Tidak, kunci utama album hanya berupa bilangan bulat yang membuat album ini unik. Anda kemudian dapat memiliki artist_idkunci asing yang merujuk pada artis tersebut. Jika Anda ingin satu trek dipetakan ke beberapa album kemudian gunakan tabel pemetaan dengan track_id, album_id. Mudah :)
Philᵀᴹ
Pertanyaan yang terkait erat.
Erwin Brandstetter

Jawaban:

16

Saya pikir Anda bisa, menggunakan diagram hubungan "berlian":

diagram

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
) ;
ypercubeᵀᴹ
sumber
1
+1 Apakah masuk akal bagi Anda untuk menambahkan batasan unik berikut ke tabel AlbumTrack: (trackID, albumID) dan (albumID, trackNo)?
AK
@AlexKuznetsov Anda benar, thnx. Saya akan "menyusutkan" PK ke saran Anda (albumID, trackNo)dan menambahkan batasan Unik lainnya juga.
ypercubeᵀᴹ
1
Ingatlah untuk mengizinkan album yang tidak memiliki artis nominal tunggal, baik dengan memiliki artis dummy yang disebut "Berbagai" atau serupa atau dengan membuat kolom artis pada tabel album dapat dibatalkan. Bahkan, Anda bisa memiliki lebih dari satu artis per lagu, jadi Anda mungkin perlu pengaturan banyak-ke-banyak di sana juga.
David Spillett
1
@ DavidSpillett Ya, kita bisa melakukan itu tetapi itu akan menyulitkan dan menyimpang dari pertanyaan yang diajukan. Pertanyaannya mengasumsikan / menentukan bahwa setiap album memiliki satu artis. Tidak mungkin memiliki artis yang berbeda per lagu, tidak ada banyak artis per album atau lagu. Memang itu bukan representasi yang sangat baik dari dunia nyata.
ypercubeᵀᴹ
1
@TimAbell Saya pikir itu kecelakaan dari Workbench di mana diagram dibuat (tidak mengenalinya sama dengan koneksi Album-AlbumTrack karena urutan kolom di
PK
2

Sayangnya saya tidak punya cukup perwakilan untuk mengomentari jawaban ypercubeᵀᴹ , jadi saya akan mengirim jawaban alternatif sebagai gantinya - Saya setuju dengan jawaban itu secara umum, tetapi saya pikir kunci primer dan kendala unik AlbumTrack salah karena album dan trek keduanya lemah. entitas. Misalnya, data yang valid berikut akan, dengan batasan yang ditentukan, dilarang:

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

Sebagai gantinya saya akan mengatur PRIMARY KEY (artistID, albumID, trackID)dan menjatuhkan batasan unik, menghasilkan:

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

Lagu masih dibatasi untuk muncul paling banyak satu kali per album.

Selain itu, pertanyaannya tidak benar-benar menentukan bahwa trek adalah entitas yang lemah (hanya itu albumnya) - jika trek sebenarnya bisa ada terlepas dari artis, Trackdan AlbumTracktabel didefinisikan sedikit berbeda:

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)
) ;
Gord Stephen
sumber