【问题标题】:Foreign Key SQL: How can I reference two attributes in one table to a composite primary key that contains 3 columns in the other table?外键 SQL:如何将一个表中的两个属性引用到另一个表中包含 3 列的复合主键?
【发布时间】:2014-06-17 06:40:08
【问题描述】:
CREATE TABLE SECTION,`
SectionNo int,
Semester CHAR(7),
CourseID CHAR(8),
PRIMARY KEY (SectionNo, Semester, CourseID),
FOREIGN KEY (CourseID) REFERENCES COURSE (CourseID),

);

CREATE TABLE REGISTRATION(
StudentID int,
SectionNo int,
Semester char(7),
PRIMARY KEY (StudentID, SectionNo, Semester),
FOREIGN KEY (SectionNo, Semester) REFERENCES Section (SectionNo, Semester), 

下划线出现在“部分”下方。错误说:“在引用的表 'Section' 中没有与外键中的引用列列表匹配的主键或候选键。”我该如何解决这个问题?!

FOREIGN KEY (StudentID) REFERENCES Student (StudentID),

);

【问题讨论】:

  • 嗯,错误信息是正确的。您不能仅使用SectionNoSemester 唯一标识Section 中的一行,因为它声明的主键还包括CourseID。如果您向我们提供有关您要建模的内容的任何实际解释,我们可能会提供更多帮助。
  • 我获得了实体、属性和数据类型来创建六个不同的表。 SECTION 表有 3 个主键,因此我不能只将 SectionNo 和 Semester 添加到 SECTION 表的一个括号中。有什么建议吗?
  • 如果通过“注册”,您的意思是“Section 表,那么不,它没有 3 个主键(实际上,在 SQL 中,您最多只能有一个 PK每个表,因此名称中包含单词 primary)。它有一个包含 3 列的 single 主键。这意味着为了引用该主键,您需要 3 列包含相同类型的数据和原版一样。
  • 假设您的Section 表包含两行(列的顺序与您的问题中显示的顺序相同):- 第 1 行包含 1,abc,def,第 2 行包含 1,abc,ghi。也就是说,它们用于两个不同的课程,但具有相同的 SectionNoSemester 值。现在我们在Registration 中插入一行:2,1,abc - 该注册意味着是什么意思?
  • 感谢您的解释。那么,既然主键中有三列,我该如何将 SectionNo 和 Semester 引用到 REGISTRATION 表?

标签: sql foreign-keys primary-key ddl


【解决方案1】:

可能

从你选择的名字判断(呃......猜测),一个学生应该在某个学期在某个课程的某个部分注册。因此,您的注册表可能缺少课程列。

3 列 PK 将有一个 3 列 FK。注册 PK 也将是所有 4 列。

但如果

如果您只录制一个学期和课程,那将是从 REGISTRATION 到 COURSE 的包含依赖项 (IND)。外键 (FK) 是键的 IND。 (嗯,在 SQL 中,它是超键的 IND,SQL KEY/UNIQUE。)从列到其他的 IND 意味着每个源子行值都将作为目标子行值出现。即源在其 IND 列上的投影减去目标在其 IND 列上的投影必须为空。

IND 意味着每个 REGISTRATION 学期课程子行值必须显示为 COURSE 子行值。这意味着

NOT EXISTS (
        SELECT Semester,Course FROM REGISTRATION
    EXCEPT SELECT Semester,Course FROM COURSE
)

如果您没有 EXCEPT/MINUS,则有一个带有 LEFT JOIN 的成语。

你愿意

您无法在大多数 SQL DBMS 中轻松表达此约束。 (尽管标准描述了功能。)您通常必须在更新时使用触发器来检查 SQL 中除少数非平凡约束之外的所有约束。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-29
    • 2023-03-17
    • 2017-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-11
    • 2020-06-27
    相关资源
    最近更新 更多