หลายต่อหลายและอ่อนแอ


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

@AlexKuznetsov คุณพูดถูกแล้ว ฉันจะ "ลด" PK ลงในข้อเสนอแนะของคุณ(albumID, trackNo)และเพิ่มข้อ จำกัด ที่ไม่ซ้ำอื่น ๆ ด้วย
ypercubeᵀᴹ

1
อย่าลืมอนุญาตให้ใช้กับอัลบั้มที่ไม่มีศิลปินชื่อเดียวไม่ว่าจะเป็นศิลปินที่มีชื่อว่า "หลากหลาย" หรือคล้ายกันหรือทำให้คอลัมน์ศิลปินของตารางอัลบั้มเป็นโมฆะ ในความเป็นจริงคุณอาจมีศิลปินมากกว่าหนึ่งคนต่อแทร็คดังนั้นคุณอาจต้องมีการจัดการหลายต่อหลายคนเช่นกัน
David Spillett

1
@DavidSpillett ใช่เราสามารถทำเช่นนั้นได้ แต่มันจะทำให้สิ่งต่าง ๆ ซับซ้อนและเบี่ยงเบนคำถามที่ถาม คำถามถือว่า / กำหนดว่าทุกอัลบั้มมีศิลปินเดียว เป็นไปไม่ได้ที่จะมีศิลปินคนละเพลง มันไม่ได้เป็นตัวแทนที่ดีของโลกแห่งความเป็นจริงแน่นอน
ypercubeᵀᴹ

1
@ TimAbell ฉันคิดว่าเป็นเหตุร้ายจาก Workbench ที่สร้างไดอะแกรม (ไม่รู้จักเช่นเดียวกับการเชื่อมต่อ Album-AlbumTrack เนื่องจากลำดับของคอลัมน์ใน PKs)
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)
) ;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.