简体   繁体   English

如何使用表中的外键另一个表中的主键

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

I have 3 tables.我有3张桌子。 Courses,CourseDestails, CourseBooking.课程、课程详情、课程预订。

Courses培训班

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

CourseDetails课程详情

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 from courses table is used as foreign key in the CourseDetails table.课程表中的 courseId 用作 CourseDetails 表中的外键。

Now I want to use CourseStartDate Location & courseId from CourseDetails table in another table called CourseBooking .现在我想用CourseStartDate位置和courseId从CourseDetails在另一个名为表表CourseBooking I know how to add CourseStartDate Location as foreign keys.我知道如何将 CourseStartDate Location 添加为外键。 But I'm confused how to add courseId from courseDetails table as foreign key in the new CourseBookings Table.但我很困惑如何从 courseDetails 表中添加 courseId 作为新CourseBookings表中的外键。

I have tried the following我已经尝试了以下

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

But there is an error saying但是有一个错误说

Can't create table 'b8040777_db1.CourseBookings'无法创建表“b8040777_db1.CourseBookings”

Supports transactions, row-level locking, and foreign keys支持事务、行级锁定和外键

There are several issues with the declaration of table CourseBookings .CourseBookings的声明有几个问题。


ISSUE 1问题 1

This :这个 :

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

Should be written as :应该写成:

FOREIGN KEY (courseId) REFERENCES CourseDetails(courseId),

ISSUE 2问题 2

One of the columns of CourseDetails , that is referenced by a foreign key of table CourseBookings , has no index.一列CourseDetails ,由表的外键引用CourseBookings ,没有索引。

From the documentation :文档

MySQL requires indexes on foreign keys and referenced keys so that foreign key checks can be fast and not require a table scan. MySQL 需要外键和引用键的索引,以便外键检查可以快速并且不需要表扫描。 In the referencing table, there must be an index where the foreign key columns are listed as the first columns in the same order.在引用表中,必须有一个索引,其中外键列以相同的顺序列为第一列。 Such an index is created on the referencing table automatically if it does not exist.如果引用表不存在,则会在引用表上自动创建此类索引。

In table CourseDetails :在表CourseDetails

  • courseId had an index automatically created because it references Courses(courseId) courseId有一个自动创建的索引,因为它引用了Courses(courseId)
  • CourseStartDate has no index but it is the first column in the index automatically generated by the primary key constraint declaration CourseStartDate没有索引但它是主键约束声明自动生成的索引中的第一列
  • Location has no index and it is only the second column in the primary key index --> it is not possible to create a foreign key referencing it, an error is raised when you try Location没有索引,它只是主键索引中的第二列 --> 无法创建引用它的外键,尝试时会引发错误

SOLUTION 1解决方案 1

It is always possible to add the missing index to the table, by adding this to the CREATE TABLE CourseDetails statement :通过将其添加到CREATE TABLE CourseDetails语句,始终可以将缺失的索引添加到CREATE TABLE CourseDetails中:

INDEX idx_Location (Location)

SOLUTION 2解决方案 2

In your use case, I suspect that what you actually need is a multicolumn foreign key (supported in InnoDB only), that references the primary key of CourseDetails (an index already exists on these columns).在您的用例中,我怀疑您实际需要的是一个多列外键(仅在 InnoDB 中支持),它引用CourseDetails的主键(这些列上已经存在索引)。 This will allow you to associate each record of CourseBookings with a unique parent record in CourseDetails .这将让你的每一个记录相关联CourseBookings与独特的父记录CourseDetails

Suggestion of DDL : 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)
 );

SOLUTION 3解决方案 3

If solution 2 fits for your use case, then it means that your schema can be optimized by creating an autoincremented integer primary key on table CourseDetails .如果解决方案 2 适合您的用例,则意味着可以通过在表CourseDetails上创建自动递增的整数主键来优化您的架构。 The existing primary key can be turned into a UNIQUE constraint.现有的主键可以变成UNIQUE约束。 Then, in table CourseBookings , you can just store a foreign key to that column.然后,在表CourseBookings ,您可以只存储该列的外键。

This would give you a simple and efficient way to relate one table to the other, while avoiding duplicating information across tables (this actually leaves you with just 3 columns in CourseBookins ).这将为您提供一种将一个表与另一个表相关联的简单而有效的方法,同时避免跨表复制信息(这实际上让您在CourseBookins只有 3 列)。

In relational database design it is usually a good practice to create such a primary key on most tables.在关系数据库设计中,在大多数表上创建这样的主键通常是一种很好的做法。 You could consider adding one to other tables too.您也可以考虑向其他表添加一个。

Example :例子 :

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, just in case : PS,以防万一:

FOREIGN KEY (GuestNo) REFERENCES Guest(GuestNo)

Does table Guest exists in your schema (you did not show the CREATE TABLE for it) ?Guest是否存在于您的架构中(您没有为其显示CREATE TABLE )?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM