Çoktan Çokya ve Zayıf Varlıklar


16

Başka biri tarafından tanımlanmadan var olamayan bir varlığım var ve bu varlığın çoktan çoğa ilişkiye katılmasını istiyorum.

Örnek: Bir sanatçının bir albümü vardır (albüm sanatçı olmadan var olamaz), albümün de çok sayıda parçası vardır, ancak aynı parça birçok albümde bulunabilir.

Bu yüzden albüm ve şarkılar arasında çoktan çoğa bir ilişkimiz var.

Albüm zayıf bir varlıksa, birincil anahtarı sanatçıyı referans alan yabancı bir anahtardır, bu nedenle çoktan çoğa bir ilişkiyi temsil eden başka bir tablonun yabancı anahtarı olamaz.

Soru şudur: SQL'de bu tür bir ilişkiye sahip olmak mümkün mü ve eğer öyleyse, bunu nasıl ifade edebilirim?


Hayır, albüm birincil anahtarı yalnızca albümü benzersiz yapan bir tam sayı olabilir. Daha sonra artist_idsanatçıyı referans alan yabancı bir anahtarınız olabilir . Tek bir parçanın birden fazla albüme eşlenmesini istiyorsanız ile eşleme tablosu kullanın track_id, album_id. Kolay :)
Philᵀᴹ

Yanıtlar:


16

Bence, bir "elmas" ilişki şeması kullanarak:

diyagram

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 tablosuna şu benzersiz kısıtlamaları eklemeniz sizin için anlamlı olur mu: (trackID, albumID) ve (albumID, trackNo)?
AK

@AlexKuznetsov Haklısın thnx. PK'yı önerdiğine "küçültecağım" (albumID, trackNo)ve diğer Benzersiz kısıtlamayı da ekleyeceğim.
ypercubeᵀᴹ

1
Tek bir nominal sanatçısı olmayan albümlere, "Çeşitli" veya benzeri adlı bir kukla sanatçıyla veya albüm tablosunun sanatçı sütununu boş bırakılarak izin vermeyi unutmayın. Aslında, parça başına birden fazla sanatçıya sahip olabilirsiniz, bu yüzden orada da çoktan çoğa bir düzenlemeye ihtiyacınız olabilir.
David Spillett

1
@DavidSpillett Evet, bunu yapabiliriz, ancak işleri karmaşıklaştıracak ve sorulan sorudan sapacaktır. Soru, her albümün tek bir sanatçısının olduğunu varsayar / belirler. Parça başına farklı sanatçıya sahip olmak mümkün değil, albüm veya parça başına ne fazla sanatçı var. Gerçekten de gerçek dünyanın çok iyi bir temsili değildir.
ypercubeᵀᴹ

1
@TimAbell Bence şemaların oluşturulduğu Workbench'ten gelen bir aksilik (PK'lardaki sütunların sırası nedeniyle Album-AlbumTrack bağlantısıyla aynı şekilde tanınmıyor)
ypercubeᵀᴹ

2

Ne yazık ki ypercubeᵀᴹ'un cevabı hakkında yorum yapmak için yeterli temsilcim yok , bu yüzden alternatif bir cevap göndereceğim - genel olarak bu cevaba katılıyorum, ancak AlbumTrack albümlerin ve parçaların her ikisinin de zayıf olduğu göz önüne alındığında birincil anahtarın ve benzersiz kontraksiyonların yanlış olduğunu düşünüyorum varlıklar. Örneğin, aşağıdaki geçerli verilere, öngörülen kısıtlamalarla izin verilmez:

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

Bunun yerine PRIMARY KEY (artistID, albumID, trackID), benzersiz kısıtlamayı ayarlayıp bıraktım , sonuç olarak:

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

Parçaların her albüm için en fazla bir kez olmaya devam etmesi sınırlıdır.

Ayrıca, soru aslında parçaların zayıf varlıklar olduğunu belirtmez (sadece albümler) - parçalar sanatçılardan bağımsız olarak mevcutsa, Trackve AlbumTracktabloları biraz farklı tanımlanır:

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)
) ;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.