[英]How to make a no primary key with datatype sting as foreign key in another table
[英]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.