【问题标题】:A Foreign key referencing multiple unique key引用多个唯一键的外键
【发布时间】:2016-07-10 13:03:01
【问题描述】:

我有 3 张桌子:

class_a

     CREATE TABLE class_a (
       id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
       std_id INT NOT NULL UNIQUE,
       name varchar(225) NOT NULL)

class_b

     CREATE TABLE class_b (
       id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
       std_id INT NOT NULL UNIQUE,
       name varchar(225) NOT NULL)

sn_number

      CREATE TABLE sn_number (
       id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
       pin INT NOT NULL UNIQUE,
       serial VARCHAR(255) NOT NULL UNIQUE,
       std_id INT NULL DEFAULT NULL,
       FOREIGN KEY(std_id) REFERENCES class_a(std_id)
       )

如何将class_aclass_b 表中唯一的std_id 引用为sn_number 表中的外键。

我想实现类似ALTER TABLE sn_number ADD FOREIGN KEY(std_id) REFERENCES class_a(std_id), class_b(std_id)

我试过这样做ALTER TABLE sn_number ADD FOREIGN KEY(std_id) REFERENCES class_a(std_id)

紧随其后

ALTER TABLE sn_number ADD FOREIGN KEY(std_id) REFERENCES class_b(std_id)sn_number 表上,但会继续相互覆盖。

我已阅读以下内容: Foreign Key Referencing Multiple Tables

Composite key as foreign key (sql) 但我找不到解决问题的方法。

【问题讨论】:

  • 出现此问题是在暗示您在数据库设计中存在错误。班级不是学生。因此,您通常不会通过类表引用 std_id,而是通过学生表。你应该考虑一下为什么你有两个类表,因为当你想连接时你可能会遇到同样的问题,例如老师或房间上课。基本上:存在类。有学生。存在 sn_numbers。每个人都有一张桌子,并将它们链接起来(如果你愿意,你可以直接绘制它们并用线条连接它们)。如果您需要专业化,您可以稍后添加。
  • 谢谢。这对我帮助很大。
  • @Abk 与@Solarflare 的评论和另一个答案相反,您需要来自同一个表和列列表的两个外键并不是设计不佳的症状。 (虽然你的设计很糟糕。)关于你的代码的问题,请参阅我的答案。
  • @Abk 既然我回来了:作为修正:我没有问sn_numbers的含义。如果它们是学生独有的,您可以使用学生表并将 pin/sn_number 添加到该表(它基本上是两个实体的合并,具有 1:1 的关系)。但是由于您在 sn_number 中的 std_id 可以为空,我想也可能有 sn_numbers 出于其他原因(可能是未分配的身份证)。反之亦然,您可以从类中引用 sn_numbers 中的 std_id 列(将 sn_numbers 表视为 student_id 表)。这样做只是有实际原因(表数),没有逻辑。
  • 您希望 sn_number 中的非 NULL std_id 值在 both class_a 和 class_b 中吗? (请参阅我的答案。)或者 either (异或或包含-或)? (请参阅我对“reminiscent 的回答。)或者您是否希望 class_a 和 class_b 中的 std_id 值都在 sn_number 中??(这意味着您希望 class_a FK (std_id) REFERENCES sn_number (std_id) 和 class_b FK (std_id) REFERENCES sn_number (std_id) 带有 sn_number std_id NOT NULL.) PS 请显示您的 DDL 和相应的错误消息

标签: mysql database foreign-keys unique-key


【解决方案1】:

外键只能引用一个父表。这是 SQL 语法和关系理论的基础。

您可以做的是添加另一个表 classesstudents 包含所有 std_id ,然后只需将 FK 引用到它。

【讨论】:

  • 不,您可以声明任意数量的约束。但每个约束名称只有一个。
【解决方案2】:

由于您没有在FOREIGN KEY 声明中明确给出约束名称,DBMS 由表名称sn_number 组成。您的问题是您每次都隐含地声明相同的约束名称,因此该名称的旧信息丢失了。只需针对表列列表REFERENCES表列列表的不同情况使用不同的显式约束名称即可。

CONSTRAINT fk_sn_number_a FOREIGN KEY(std_id) REFERENCES class_a(std_id)
CONSTRAINT fk_sn_number_b FOREIGN KEY(std_id) REFERENCES class_b(std_id)

只需了解Using FOREIGN KEY Constraints 的基础知识。

PS 正如评论中所说,这是一个糟糕的设计。但与评论和另一个答案相反,您需要来自同一个表和列列表的两个外键并不是设计不佳的症状。但是请注意,人们通常在有问题的设计中使用“外键引用多个表”时遇到的问题是,他们认为设计的表需要从一个地方到两个地方的外键,而实际上不需要。这样的设计甚至不涉及外键,它只涉及让人想起外键的东西。

【讨论】:

  • 无论是你还是我都没有拿到他的表——我理解如下:有些学生在a班,有些在b班,大部分在sn_number,所以他试图创建一个参考到学生的完整列表作为班级表的联合。这不是 sql 的工作方式,您不能以这种方式使用外键来执行此操作。因此,最基本的想法是:一个学生 id 是指一个学生表(可能间接地指向一个关键候选人)。有理由使用你的构造(因此是“提示”而不是“这总是错误的”),但对于初学者来说没有。您在技术上可以做到并不意味着它是有意义的。
  • 我刚刚对有关 Abk 可能意味着的各种事情的问题添加了评论。回复“他们中的大多数都在 sn_number 中”你不是说 all 吗?关于“学生 id 是指学生表”,我同意这可能是他们想要的,使用 sn_number 作为“学生表”,但是 FK 则相反,并且 sn_number 必须不是 NULL。重新“没有意义”如果 nr_number ids 识别出课堂上学生可用的储物柜,它确实如此。
  • 我的评论主要是针对他作为补充解释。我 120% 确定你知道外键是如何工作的,我可能会在前 8 个单词之后停下来,你就会知道我想说什么。除了“全部”之外 - 我实际上的意思是“大多数”,以防参考是指他描述的方向(因为 sn_number 可能是也可能不是丢失的学生表)。我的意思是,使用所有可能的技术方法“没有意义”。在接下来的 3 年内,他将不再需要双外键,如果他需要,我很确定它可以通过其他方式实现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-25
  • 1970-01-01
  • 1970-01-01
  • 2012-02-01
  • 2015-04-17
  • 1970-01-01
相关资源
最近更新 更多