Багато до багатьох та слабких організацій


16

У мене є сутність, яка не може існувати, не визначившись іншим, і я хочу, щоб ця організація брала участь у відносинах «багато-багато».

Приклад: у виконавця є альбом (альбом не може існувати без виконавця), у альбому також багато композицій, але однаковий трек може існувати у багатьох альбомах.

Таким чином, ми маємо багато-багато-багато стосунків між альбомом і треками.

Якщо альбом є слабкою сутністю, то його первинний ключ - це зовнішній ключ, що посилається на виконавця, тому він не може бути стороннім ключем до іншої таблиці, що представляє відносини «багато-багато».

Питання: чи можна мати такі відносини в SQL, і якщо так, то як це виразити?


Ні, основним ключем альбому було б просто ціле число, яке робить альбом унікальним. Потім у вас може бути artist_idіноземний ключ, який посилається на виконавця. Якщо ви хочете, щоб одна композиція була відображена у декількох альбомах, тоді використовуйте таблицю зі відображенням track_id, album_id. Легко :)
Philᵀᴹ

Відповіді:


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)?
АК

@AlexKuznetsov Ви праві, Thnx. Я "скорочу" ПК до запропонованих вами пропозицій (albumID, trackNo)і додамо також інше унікальне обмеження.
ypercubeᵀᴹ

1
Пам’ятайте, щоб дозволити альбоми, у яких немає єдиного номінального виконавця, або шляхом манекена виконавця під назвою "Різноманітний" або подібного, або зробивши стовпцем виконавця таблиці альбомів нульовою. Насправді у вас може бути більше одного виконавця на доріжку, тому вам може знадобитися також аранжування багато-багато.
Девід Спіллетт

1
@DavidSpillett Так, ми могли б це зробити, але це ускладнить справи та відхилиться від поставленого питання. Питання передбачає / диктує, що кожен альбом має одного виконавця. Неможливо мати різних виконавців на трек, ні багато виконавців на альбом чи трек. Дійсно, це не дуже добре представлення реального світу.
ypercubeᵀᴹ

1
@TimAbell Я думаю, що це неправильна робота з Workbench, де були створені діаграми (не розпізнаючи це так само, як з'єднання Album-AlbumTrack завдяки порядку стовпців у ПК)
ypercubeᵀᴹ

2

На жаль, у мене не вистачає респондентів, щоб коментувати відповідь ypercube so , тому я замість цього опублікую альтернативну відповідь - я згоден з цією відповіддю, але думаю, що основний ключ та унікальні протипоказання 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)
) ;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.