答案 0 :(得分:1)
您想要的肯定可以实现。请考虑以下表定义:
create table Tbl_Course(
CrsId int primary key,
CrsName varchar(100)
);
create table Tbl_Student(
StdId int primary key,
StdCourse1 int,
StdCourse2 int,
StdCourse3 int,
foreign key (StdCourse1) references Tbl_Course(CrsId),
foreign key (StdCourse2) references Tbl_Course(CrsId),
foreign key (StdCourse3) references Tbl_Course(CrsId)
);
完成此设置后,您可以插入示例数据:
insert into Tbl_Course values
(1001, 'MATHS'),
(1002, 'PHYSICS'),
(1003, 'CHEMISTRY'),
(1004, 'ARTS');
insert into Tbl_Student values
(1, 1001, 1002, 1003),
(2, 1002, 1003, 1004),
(3, 1004, null, null);
如果您尝试在子表中插入父表中不存在的值,则会出现错误:
insert into Tbl_Student values(4, 1005, null, null);
INSERT语句与FOREIGN KEY约束“ FK__Tbl_Stude__StdCo__38996AB5”发生冲突
但是应注意,表Tbl_Student
的设计未规范化。如果学生参加超过3门课程怎么办?您将需要向表中添加更多列。您如何检查用户是否参加了给定的课程?您需要签入3个不同的列。对于遵循标准规范化规则的替代设计,请参见Dai的以下答案。
答案 1 :(得分:1)
Your design is not correctly normalized。不要使用列来表达多个关系,而要使用行。
此外,匈牙利表示法也皱了皱眉。避免使用对象标识符前缀,例如“ Tbl_
”。无需在列名中使用缩写。在可能的情况下,请始终使用完整的拼写,以便其他人可以理解您的系统(又称“自记录代码”)。
考虑这样的设计:
CREATE TABLE Students (
StudentId int NOT NULL PRIMARY KEY IDENTIY(1,1),
-- etc
)
CREATE TABLE Courses (
CourseId int NOT NULL PRIMARY KEY IDENTIY(1,1),
Name nvarchar(100) NOT NULL,
-- etc
)
CREATE TABLE StudentsInCourses (
StudentId int NOT NULL PRIMARY KEY, -- Composite primary key
CourseId int NOT NULL PRIMARY KEY,
CONSTRAINT FOREIGN KEY ( StudentId ) REFERENCES Students ( StudentId ),
CONSTRAINT FOREIGN KEY ( CourseId ) REFERENCES Courses ( CourseId )
)
此设计允许学生无限制地参加零个或多个课程,并允许使用JOIN
and other relational operators直接查询在校学生关系,而您的设计却没有如果学生要学习三门以上的课程,或者您要运行涉及某个课程的学生的查询,而该课程可以是Course1
,Course2
或{{1} }。
此外,由于两列都参与Course3
中的复合主键,因此该设计使学生不可能多次参加同一课程(如果不希望这样做,请使用更具体的要求)