簡體   English   中英

如何使用表中的外鍵另一個表中的主鍵

[英]How to use a Foreign key in a table a primary key in another table

我有3張桌子。 課程、課程詳情、課程預訂。

培訓班

CREATE TABLE Courses (
    courseId int NOT NULL,
    courseName varchar(255),
    level varchar(255),
    description varchar(255),  
    PRIMARY KEY (courseId)
);

課程詳情

CREATE TABLE CourseDetails (
    CourseStartDate int NOT NULL,
    Location varchar(255) NOT NULL,
    MaxNoPlaces int,
    Length int,
    Instructor varchar(255),
    TotalPlacesBooked int,
    NoPlacesCancelled int,
    AdultPrice int,
    ChildPrice int, 
    courseId int,
    CONSTRAINT PK_CourseDetails PRIMARY KEY (CourseStartDate,Location,courseId),
    FOREIGN KEY (courseId) REFERENCES Courses(courseId)
);

課程表中的 courseId 用作 CourseDetails 表中的外鍵。

現在我想用CourseStartDate位置和courseId從CourseDetails在另一個名為表表CourseBooking 我知道如何將 CourseStartDate Location 添加為外鍵。 但我很困惑如何從 courseDetails 表中添加 courseId 作為新CourseBookings表中的外鍵。

我已經嘗試了以下

CREATE TABLE CourseBookings (
    CourseStartDate int NOT NULL,
    Location varchar(255) NOT NULL,
    GuestNo int, 
    courseId int,
    CONSTRAINT PK_CourseDetails PRIMARY KEY (CourseStartDate,Location,GuestNo,courseId),
    FOREIGN KEY (courseId) REFERENCES CourseDetails.courseId(courseId),
    FOREIGN KEY (CourseStartDate) REFERENCES CourseDetails(CourseStartDate),
    FOREIGN KEY (Location) REFERENCES CourseDetails(Location),
    FOREIGN KEY (GuestNo) REFERENCES Guest(GuestNo)
 );

但是有一個錯誤說

無法創建表“b8040777_db1.CourseBookings”

支持事務、行級鎖定和外鍵

CourseBookings的聲明有幾個問題。


問題 1

這個 :

FOREIGN KEY (courseId) REFERENCES CourseDetails.courseId(courseId),

應該寫成:

FOREIGN KEY (courseId) REFERENCES CourseDetails(courseId),

問題 2

一列CourseDetails ,由表的外鍵引用CourseBookings ,沒有索引。

文檔

MySQL 需要外鍵和引用鍵的索引,以便外鍵檢查可以快速並且不需要表掃描。 在引用表中,必須有一個索引,其中外鍵列以相同的順序列為第一列。 如果引用表不存在,則會在引用表上自動創建此類索引。

在表CourseDetails

  • courseId有一個自動創建的索引,因為它引用了Courses(courseId)
  • CourseStartDate沒有索引但它是主鍵約束聲明自動生成的索引中的第一列
  • Location沒有索引,它只是主鍵索引中的第二列 --> 無法創建引用它的外鍵,嘗試時會引發錯誤

解決方案 1

通過將其添加到CREATE TABLE CourseDetails語句,始終可以將缺失的索引添加到CREATE TABLE CourseDetails中:

INDEX idx_Location (Location)

解決方案 2

在您的用例中,我懷疑您實際需要的是一個多列外鍵(僅在 InnoDB 中支持),它引用CourseDetails的主鍵(這些列上已經存在索引)。 這將讓你的每一個記錄相關聯CourseBookings與獨特的父記錄CourseDetails

DDL的建議:

CREATE TABLE CourseBookings (
    CourseStartDate int NOT NULL,
    Location varchar(255) NOT NULL,
    GuestNo int, 
    courseId int,
    CONSTRAINT PK_CourseDetails PRIMARY KEY (CourseStartDate,Location,courseId,GuestNo),
    FOREIGN KEY (CourseStartDate,Location,courseId) 
        REFERENCES CourseDetails(CourseStartDate,Location,courseId),
    FOREIGN KEY (GuestNo) REFERENCES Guest(GuestNo)
 );

解決方案 3

如果解決方案 2 適合您的用例,則意味着可以通過在表CourseDetails上創建自動遞增的整數主鍵來優化您的架構。 現有的主鍵可以變成UNIQUE約束。 然后,在表CourseBookings ,您可以只存儲該列的外鍵。

這將為您提供一種將一個表與另一個表相關聯的簡單而有效的方法,同時避免跨表復制信息(這實際上讓您在CourseBookins只有 3 列)。

在關系數據庫設計中,在大多數表上創建這樣的主鍵通常是一種很好的做法。 您也可以考慮向其他表添加一個。

例子 :

CREATE TABLE CourseDetails (
    id int PRIMARY KEY AUTO_INCREMENT,
    CourseStartDate int NOT NULL,
    ...
    CONSTRAINT PK_CourseDetails UNIQUE (CourseStartDate,Location,courseId),
    FOREIGN KEY (courseId) REFERENCES Courses(courseId)
);

CREATE TABLE CourseBookings (
    id int PRIMARY KEY AUTO_INCREMENT,
    courseDetailId INT NOT NULL,
    GuestNo int, 
    CONSTRAINT PK_CourseBookings UNIQUE (courseDetailId,GuestNo),
    FOREIGN KEY (courseDetailId) REFERENCES CourseDetails(id),
    FOREIGN KEY (GuestNo) REFERENCES Guest(GuestNo)
);

PS,以防萬一:

FOREIGN KEY (GuestNo) REFERENCES Guest(GuestNo)

Guest是否存在於您的架構中(您沒有為其顯示CREATE TABLE )?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM