【问题标题】:Composite Primary Key Constraint复合主键约束
【发布时间】:2015-06-23 18:30:29
【问题描述】:

表定义:

Student(StudentID, StudentName) PK StudentID

Faculty(FacultyID, FacultyName) PK FacultyID

Course(CourseID, CourseName) PK CourseID

Qualified(FacultyID, CourseID, DateQualified) PK FacultyID CourseID

Section(SectionNo,Semester, CourseID) PK SectionNo Semester CourseID

Registration(StudentID, SectionNo, Semester) PK StudentID SectionNo Semester

如何链接表注册和部分? 注册中的 StudentID 作为学生表中 StudentID 的外键引用 但是我可以用 SectionNo 和 Semester 做什么?我可以在外键 Section_Semester (SectionNo, Semester) 上添加一个约束,但这两个属性在 Section 表中不是唯一的。在 Section 表中添加主键约束?

谢谢

【问题讨论】:

  • 那些不是表定义。 CREATE TABLE 语句是表定义。 (您可以编辑您的问题,并粘贴 CREATE TABLE 语句。)从您的描述中不清楚您是尝试在“注册”中创建引用“部分”的外键,还是尝试创建外键在引用“注册”的“部分”中。是哪个?
  • Section(SectionNo, ... 偏离了其他表的约定。 SectionNo 本身是主键(代理或自然键),或者它只是与 (Semester, CourseID) 键相关联的信息,或者它是复合键的一部分。根据这 3 个中的哪一个是正确的,必须调整 Registration 到 Section 中的外键以与 Section 主键对齐。就目前而言,您需要将CourseID 添加到Registration 并将其添加到Section 的外键中。
  • 除了借调 Stuart 和 Mike 的 cmets 之外,没有描述这些表,我们不知道您要达到什么目的,也不知道您在这两个表中哪个是父级,哪个是子级想要“链接”,或者有什么目的。如果我以标题为问题,答案是“是的,你可以”。每个 SQL 和非 SQL 平台都有不同的语法,因此您必须查找它。
  • @PerformanceDBA:欢迎回来!
  • @Mike。谢谢。我很惊讶有人记得四年前的我!

标签: sql database-design rdbms composite-key


【解决方案1】:

我看不出没有 CourseID 如何拥有完整的注册元组。如果 SectionNo 和 Semester 的组合不是唯一的,那么学生注册的是什么?本学期的所有指定部分?不,他们注册了一个特定的课程(在指定的日期、指定的时间、指定的地点开会)。

当然,我不知道Section代表什么。但无论它代表什么,它显然没有精确地缩小学生注册的范围。你必须把它包括在内。

【讨论】:

  • 嗨,TomCatt,谢谢。这里的部分表代表我猜你可以在哪个学期选择哪些课程。此处的regitration table表示哪个学生选择哪个部分(哪个学期的哪个课程)。
  • 是的。但是注册元组中没有课程信息。或者更确切地说,它可以指多门课程,因为 SectionNo 和 Semester 不是指一门课程,而是指几门课程。你必须以某种方式缩小范围。
【解决方案2】:

如果我理解正确,您是说您的 Section 表的主键为 (sectionNo,semester,courseID),因此可以有多个具有相同 sectionNo 和学期的记录?然后你想把没有 courseID 的 Registration 连接到这个表?据我所知,您不能使用“引用”子句,因为它不会链接到唯一标识符。但这并不能阻止您编写连接两个表的查询。

更新

当然,根据您想知道的内容,有许多可能的查询。如果你想知道 17 号学生曾经注册过的所有课程,你可以这样写:

select section.sectionno, section.semester, section.courseid
from registration
join section on section.sectionno=registration.sectionno 
  and section.semester=registration.semester 
where studentid=17

如果您想要给定注册记录的所有课程:

select coursed
from registration
join section on section.sectionno=registration.sectionno
  and section.semester=registration.semester
where registration.sectionno=@section
  and registration.semester=@semester
  and registration.studentid=@student

现在,嗯,写这个查询这表明学生注册了组成一个部分和学期的所有课程。这是真的?如果一个部分和学期有多个课程,学生是一次注册所有课程,还是选择单独的课程?如果他选择,那么注册似乎需要指定哪个课程。

我不知道这里的“部分”是什么意思,所以我不知道它是如何关联的。

【讨论】:

  • 嘿,杰,你理解的很清楚。由于您刚刚在回答中提到的原因,我无法编写查询来加入部分表和注册表。
  • 为什么不呢? select section.sectionno, section.semester, section.courseid from registration join section on section.sectionno=registration.registrationno and section.semester=registration.semester where studentid=17 会给你学生17注册的所有课程,例如.
  • 嘿,Jay,你能用 SQL 写下来吗?我的意思是加入部分和注册表?此外,在Registration 表中没有RegistrationNo 作为主键。它需要 StudentID、SectionNo 和 Semester 作为复合主键。
  • @CaterinaChen 哦,对不起,我的意思是sectionno,不是registrationno。无论如何,我已经更新了我的答案,也许可以解决你的问题。
  • 您好,Jay,感谢您的回复,很抱歉您没有理解我的意思。我试图加入部分表和注册表。但是由于每个表中的复合主键具有三个属性,我可以弄清楚如何使用外键来引用它。最后我放弃了那些主键,自己写代码。
猜你喜欢
  • 2013-10-06
  • 2011-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-29
  • 2015-08-19
相关资源
最近更新 更多