一个外键引用多个唯一键

问题描述:

我有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) 
     ) 

我如何引用独特std_idclass_aclass_b表中作为外键在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) 但我不能找到解决问题的办法时遇到。

+0

有这个问题是提示你,你有一个数据库设计的错误。一个班不是学生。所以你通常不会引用类表的std_id,而是引用学生表。你应该考虑为什么你有两个类表,因为当你想要连接时,你可能会遇到同样的问题。老师或房间上课。基本上:存在类。有学生。存在sn_numbers。每个表都有一个表格,并链接它们(如果你愿意,你可以从字面上绘制它们并用线条连接它们)。如果您需要专业化,您可以稍后添加它们。 – Solarflare

+0

谢谢。这真的帮了我很多。 – Abk

+0

@ Abk与@Solarflare&另一个答案的评论相反,您需要来自同一个表和列列表的两个外键不是不良设计的症状。 (虽然你的设计很差)。对于你的代码的问题,请参阅我的答案。 – philipxy

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

你可以做什么,是添加另一个表classesstudents包含所有std_id,那么就引用FK它。

+0

不,你可以声明任意数量的约束,但每个约束名称只能有一个 – philipxy

由于您的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正如在评论中指出的那样,这是一个糟糕的设计。但与&的评论相反,另一个答案是,您需要来自同一个表&列表的两个外键不是设计不佳的症状。但是请注意,人们通常在可疑设计中使用“外键引用多表”时遇到的问题是,他们认为他们的表格在设计时需要从一个地方到另外两个地方的外键,而不是这样。这样的设计甚至不涉及外键,它只是涉及让人想起外键

+0

你或我拿不到他的桌子 - 我理解如下:一些学生在课堂a,一些在课堂b,大多数在sn_number,所以他试图创建一个完整的学生列表作为类表的联合的参考。这不是SQL的工作原理,你不能用这种外键来实现这一点。因此,最基本的想法是:学生证是指一张学生表(可能是间接的关键人选)。有理由使用你的构造(因此“提示”而不是“这总是错误的”),但对于初学者来说没有。你在技术上可以做到这并不意味着它是有道理的。 – Solarflare

+0

我刚刚为Abk可能意味着的各种事情添加了一条评论。 Re“大部分都在sn_number中”你是不是指所有*他们?重新“学生ID是指学生表”我同意可能是他们想要的,使用sn_number作为“学生表”,但然后FKs走另一条路,sn_number必须不是NULL。 Re“没有意义”如果nr_number id确定班级中的学生可用的储物柜,它会这样做。 – philipxy

+0

我的评论主要是针对他作为补充说明。我120%确定你知道外键是如何工作的,我可能在前8个单词后停下来,你会知道我想说什么。除了“全部” - 我实际上是指“最多”,以防万一这个引用是按照他所描述的方向(因为sn_number可能或可能不是缺少的学生表)。我的意思是,使用所有技术可能的方法“没有意义”。在未来3年他不需要双重外键,如果他这样做,我很确定它可以以另一种方式实施。 – Solarflare