【问题标题】:SQL DDL: Recursive table with two foreign keys (MySQL)SQL DDL:具有两个外键的递归表 (MySQL)
【发布时间】:2013-07-30 15:11:59
【问题描述】:

我有一个递归的subject 表,因为一个主题可以是另一个主题的先决条件:

  • 科目可以没有先决条件
  • 一个科目可以有 1 个先决条件
  • 一个科目可以有 2 个先决条件

由于有 2 个先决条件的科目,我将 prerequisite_1prerequisite_2 列 FK 指向 subject_code 列:

CREATE TABLE subject(
    subject_code CHAR(7),
    subject_desc VARCHAR(255) NOT NULL,
    no_of_units TINYINT UNSIGNED NOT NULL CHECK(no_of_units >= 0 AND no_of_units < 13),
    prerequisite_1 CHAR(7),
    prerequisite_2 CHAR(7),
    PRIMARY KEY(subject_code),
    FOREIGN KEY(prerequisite_1, prerequisite_2) REFERENCES subject(subject_code)
)ENGINE=INNODB;

我在 SQL Fiddle 上尝试了代码,但没有创建表。

如何创建一个包含 1 个 PK 列和 2 个 FK 列指向表自身 PK 的递归表?

【问题讨论】:

  • 我认为您的语法有误,请尝试将每个外键的 foreign key 内容更改为:CONSTRAINT `subject_ibfk_1` FOREIGN KEY (`prerequisite_1`) REFERENCES `subject` (`subject_code`) (ON DELETE CASCADE?) 将所有 _1 替换为 _2 偏离路线。
  • 您可以使用单独的参考表将主题与其先决条件相关联,而不是任意将自己限制为 2 个先决条件。
  • @Barmar 到目前为止,科目最多有 2 个先决条件,但是如果我应用您的建议,必须如何完成(SQL 代码)?

标签: mysql sql foreign-keys ddl recursive-query


【解决方案1】:

不要将先决条件放在subject 表中,而是使用多对多关系表:

CREATE TABLE prerequisite (
    subject_code CHAR(7),
    prerequisite CHAR(7),
    PRIMARY KEY (subject_code, prerequisite),
    FOREIGN KEY (subject_code) REFERENCES subject(subject_code),
    FOREIGN KEY (prerequisite) REFERENCES subject(subject_code)
)

这允许任意数量的先决条件。

【讨论】:

  • +1 当先决条件的数量未知时,此解决方案更具消耗性。我猜的缺点是一个额外的表,行数可能非常大(O(#subject^2))。
【解决方案2】:

您需要将它们拆分为两个单独的外键,并且您可能应该(但不必)命名它们;

CREATE TABLE subject(
    subject_code CHAR(7),
    subject_desc VARCHAR(255) NOT NULL,
    no_of_units TINYINT UNSIGNED NOT NULL 
       CHECK(no_of_units >= 0 AND no_of_units < 13),
    prerequisite_1 CHAR(7),
    prerequisite_2 CHAR(7),
    PRIMARY KEY(subject_code),
    FOREIGN KEY fk_pr1(prerequisite_1) REFERENCES subject(subject_code),
    FOREIGN KEY fk_pr2(prerequisite_2) REFERENCES subject(subject_code)
) ENGINE=INNODB;

An SQLfiddle.

【讨论】:

  • 谢谢,这行得通(虽然我删除了 fk_pr1 和 fk_pr2),而且我还能够完美地插入数据。请问为什么我必须(我不能)命名外键?它有什么意义?
【解决方案3】:

所以,这是我的评论:

我认为您的语法有误,请尝试将每个外键的 foreign key 内容更改为:

CREATE TABLE subject(
    .........

    CONSTRAINT `subject_ibfk_1` FOREIGN KEY (`prerequisite_1`) REFERENCES `subject` (`subject_code`),

    CONSTRAINT `subject_ibfk_2` FOREIGN KEY (`prerequisite_2`) REFERENCES `subject` (`subject_code`)

)ENGINE=INNODB;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-14
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 2018-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多