Sfortunatamente non ho abbastanza rappresentante per commentare la risposta di ypercubeᵀᴹ , quindi posterò una risposta alternativa - Sono d'accordo con quella risposta in generale, ma penso che la chiave primaria e le contraddizioni uniche AlbumTrack
siano errate dato che album e tracce sono entrambi deboli entità. Ad esempio, i seguenti dati validi verrebbero vietati, con i vincoli prescritti:
artistID | albumID | trackID | trackNo
----------+---------+---------+---------
1 | 1 | 1 | 1
2 | 1 | 1 | 1
Invece vorrei impostare PRIMARY KEY (artistID, albumID, trackID)
e rilasciare il vincolo univoco, risultando in:
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)
) ;
Le tracce sono ancora obbligate a verificarsi al massimo una volta per album.
Inoltre, la domanda in realtà non specifica che le tracce sono entità deboli (solo che gli album lo sono) - se in realtà le tracce possono esistere indipendentemente dagli artisti, le tabelle Track
e AlbumTrack
sono definite in modo leggermente diverso:
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
chiave esterna che fa riferimento all'artista. Se si desidera mappare una singola traccia su più album, utilizzare una tabella di mappatura contrack_id, album_id
. Facile :)