ความสัมพันธ์ต่างประเทศของ SQL Server บนคีย์หลักสองคอลัมน์

ฉันมีตารางตัวอย่างสามตารางต่อไปนี้ (การสาธิตแบบง่ายเพื่อวัตถุประสงค์ในการตั้งคำถาม):

CREATE TABLE Teams 
(
    Id int IDENTITY(1,1) NOT NULL,
    Name varchar(50) NOT NULL,
    PRIMARY KEY (Id)
)

CREATE TABLE TeamGroups 
(
    Id int NOT NULL,
    TeamId int NOT NULL,
    PRIMARY KEY (Id,TeamId)
)

CREATE TABLE RoomBookings
(
    Id int NOT NULL,
    TeamGroupId int NOT NULL,
    RoomId int NOT NULL,
    PRIMARY KEY (Id)
)

และฉันได้ตั้งค่าคีย์ต่างประเทศต่อไปนี้แล้ว:

ALTER TABLE TeamGroups WITH CHECK
ADD CONSTRAINT [FK_TeamGroups_Teams] 
    FOREIGN KEY (TeamId) REFERENCES Teams(Id)

แนวคิดก็คือ แต่ละ Team สามารถมีค่าเป็นศูนย์หรือมากกว่า TeamGroups และแต่ละ TeamGroup สามารถมีศูนย์หรือมากกว่า RoomBookings

เพื่อสะท้อนถึงสิ่งนั้น ฉันต้องการเพิ่มคีย์ต่างประเทศจากตาราง RoomBookings ลงในตาราง TeamGroups

ฉันลองใช้ความสัมพันธ์ GUI ใน Management Studio เพื่อสร้างคีย์ต่างประเทศ (ตารางคีย์หลัก: TeamGroups.ID, ตารางคีย์ต่างประเทศ: RoomBookings.TeamGroupId) แต่ฉันได้รับข้อผิดพลาด:

คอลัมน์ในตาราง 'TeamGroups' ไม่ตรงกับคีย์หลักที่มีอยู่หรือข้อจำกัด UNIQUE

ฉันคิดว่าเป็นเพราะตาราง TeamGroups มีคีย์หลักสองคอลัมน์ใช่ไหม

ฉันไม่ต้องการสร้างข้อจำกัดคีย์ต่างประเทศจากตาราง TeamGroups (เช่น คีย์มีอยู่ในตาราง TeamGroups) เนื่องจากในที่สุดตารางจะถูกนำมาใช้โดยตารางอื่น (เช่น EquipmentBookings, GroupManagers ฯลฯ )

ความช่วยเหลือใด ๆ ?


comment
หากคีย์หลักของคุณประกอบด้วยคอลัมน์มากกว่าหนึ่งคอลัมน์ คีย์ส่วนหน้า ทั้งหมด ต้องมี คอลัมน์เหล่านั้นทั้งหมดด้วย ไม่มีทางแก้ไขได้ แต่ฉันไม่เข้าใจว่าทำไมคุณถึงได้รับข้อผิดพลาดนี้ขณะพยายามเชื่อมโยง TeamGroups ไปยัง Team ตามคอลัมน์ Team.Id.... นั่นน่าจะใช้ได้ดี   -  person marc_s    schedule 19.11.2015
comment
ทำงานได้ดีเมื่อเชื่อมโยง TeamGroups กับ Team TeamGroups ถึง RoomBookings ที่ล้มเหลว   -  person Sk93    schedule 19.11.2015
comment
ฉันได้อัปเดตคำสั่งที่แสดงแล้ว ฉันใช้ Management Studio เพื่อเขียนสคริปต์ แต่จะแก้ไขเมื่อคัดลอก + วาง ไม่ต้องสนใจ SQL เลย ไม่ใช่ปัญหา แต่มีไว้เพื่อแสดงคีย์อื่นที่มีอยู่แล้ว สิ่งที่ฉันต้องการทำคือเพิ่มคีย์จาก RoomBookings ถึง TeamGroups   -  person Sk93    schedule 19.11.2015


คำตอบ (1)


หากคีย์หลักของคุณประกอบด้วยมากกว่าหนึ่งคอลัมน์ คีย์ส่วนหน้า ทั้งหมด ก็ ต้องมี คอลัมน์เหล่านั้นทั้งหมดด้วย - ไม่มีทางแก้ไขได้

แต่ฉันไม่เข้าใจว่าทำไมคุณถึงได้รับข้อผิดพลาดนี้ขณะพยายามเชื่อมโยง TeamGroups ไปยัง Team ตามคอลัมน์ Team.Id.... นั่นน่าจะใช้ได้ดี

ลองใช้สิ่งนี้:

ALTER TABLE TeamGroups WITH CHECK 
   ADD CONSTRAINT [FK_TeamGroups_Teams] 
   FOREIGN KEY (TeamId) REFERENCES Teams(Id);

คุณมี Teams (ซึ่งไม่ใช่คอลัมน์ที่ถูกต้องใน TeamGroups เลย) และคุณมี REFERENCES Teams.id ซึ่งผิด - จะต้องเป็น REFERNCES Teams(Id); (คอลัมน์ในวงเล็บ - ไม่ใช่สัญกรณ์ "จุด")

อัปเดต: จาก TeamGroups ถึง RoomBookings - ใช่.... ใช้ทั้งสองคอลัมน์จาก TeamGroups ในตาราง RoomBookings ของคุณ - หรืออะไรจะหยุดคุณไม่ให้สร้างคอลัมน์ TeamGroups.Id เป็น INT IDENTITY แล้วให้ PK แค่นี้ หนึ่งคอลัมน์?? มีเหตุผลที่ดีสำหรับสิ่งนั้น??

CREATE TABLE TeamGroups 
(
    TeamGroupId int NOT NULL,
    TeamId int NOT NULL,

    PRIMARY KEY (TeamGroupId)
)

ALTER TABLE dbo.RoomBookings
   ADD CONSTRAINT FK_RoomBookings_TeamGroup
   FOREIGN KEY TeamGroupId REFERENCES TeamGroups(TeamGroupId)
person marc_s    schedule 19.11.2015
comment
TeamGroups สามารถประกอบด้วยหนึ่งทีมขึ้นไป เช่น TeamGroup 1 สามารถประกอบด้วยทีม A และทีม B ซึ่งหมายความว่าจะมีสองแถวใน TeamGroup ทั้งคู่มี Id เป็น 1 แต่มีค่าต่างกันใน TeamId - person Sk93; 19.11.2015
comment
@ Sk93: ทีมใดสามารถเป็นส่วนหนึ่งของกลุ่มทีมมากกว่าหนึ่งกลุ่มได้หรือไม่? หากเป็นเช่นนั้น คุณจะต้องสร้าง TeamGroup ตารางข้อมูลที่เหมาะสม และใส่ตารางความสัมพันธ์ m:n ระหว่าง Team ถึง TeamGroup ถ้าไม่ - หากทีมใดทีมหนึ่งเคยเป็นส่วนหนึ่งของ TeamGroup เดียว (หรือไม่มีเลย) แสดงว่าความสัมพันธ์ของคุณถอยหลัง - ควรอยู่ระหว่าง Team ถึง TeamGroups (Team ควรมีคอลัมน์ TeamGroupId - ไม่ใช่วิธีอื่น) - person marc_s; 19.11.2015
comment
ใช่มันสามารถ ฉันจะปรับ. ขอบคุณ. - person Sk93; 19.11.2015