我可以为来自两个不同表的外键使用两个不同值的一列吗?

时间:2019-04-10 20:59:00

标签: sql database

所以我有此表地址

CREATE TABLE Addresses
(
Address_ID VARCHAR (10) PRIMARY KEY,
Student_ID/Staff_Number VARCHAR (20),
Name CHAR (50),
Surname CHAR (30),
Building/House_Number INT (5),
Street CHAR (20),
City CHAR (30),
Postcode VARCHAR (10)
FOREIGN KEY (Student_ID) REFERENCES Students (Student_ID)
);

问题是,Student_ID/Staff_Number VARCHAR (20),行要么来自学生表,要么来自职员表。那我可以分配两个外键吗?

3 个答案:

答案 0 :(得分:0)

否,那是不可能的。

您可能正在考虑在设计中实现某种继承模式,其中您拥有诸如“人”基表之类的内容,学生表和职员表均会扩展,而外键指向该表。

P.S。您的varchar Ids列是聚集索引吗?这可能会降低性能,请考虑使用代理身份列进行集群

答案 1 :(得分:0)

好的,这不像是“我怎么做特定的X?”以及更多“我应该如何 做到这一点?”

因为,老实说,您不想要按照尝试布局的方式进行操作。

让我给您一些从数据库布局角度来看更好的选择:

  1. 逆转关系(我的建议)。让“职员/学生”代替“地址”表与职员/学生联系在一起 绑定到AddressID。
  2. 将两个表合并为一个人表(另一个非常好的选择)。这样,您只有一个表与“地址”表链接。然后,如果某些字段仅适用于某人的一种类型(仅限员工,仅限学生等)-将这些 only 列卸载到仅适用于那些人的专用表中领域。因此,您可能具有一个包含所有基本信息的Person表,一个链接到Person表的Address表,一个带有GradeLevel列的Student表和一个带有SubjectTaught列的Staff表。
  3. 有两个单独的地址表:一个用于学生,一个用于员工。是否要链接到学生表?太好了-您已经 在StudentAddress表中获得了StudentID。和一样 员工。
  4. 有一列指示收件人类型。学生为0,工作人员为1。根本不要放入外键约束。
  5. 有两列-一列用于学生ID,一列用于员工ID (假定一列始终为空。) 对应表的外键(外键可以为null 值。)

...所有这些听起来都比尝试做一个分裂外键更好。更糟糕的是,如果学生和工作人员共享一个ID,会发生什么?该地址适用于哪个实体?

答案 2 :(得分:-1)

您始终可以在单个列上添加多个外键约束,但是将强制执行其中的全部,而不仅仅是其中之一。例如:

CREATE TABLE Addresses
(
Address_ID VARCHAR (10) PRIMARY KEY,
Student_ID VARCHAR (20),
Name CHAR (50),
Surname CHAR (30),
Building/House_Number INT (5),
Street CHAR (20),
City CHAR (30),
Postcode VARCHAR (10),
FOREIGN KEY (Student_ID) REFERENCES Students (Student_ID)
FOREIGN KEY (Student_ID) REFERENCES Staff (Staff_ID)
);

这可能不是您想要的。您可能想要的是有两列,每一列指向一个单独的表;对于列中的那些,始终为null,而另一个则不为null。您可以如下所示进行操作:

CREATE TABLE Addresses
(
Address_ID VARCHAR (10) PRIMARY KEY,
Student_ID VARCHAR (20),
Staff_ID VARCHAR(20),
Name CHAR (50),
Surname CHAR (30),
Building/House_Number INT (5),
Street CHAR (20),
City CHAR (30),
Postcode VARCHAR (10),
FOREIGN KEY (Student_ID) REFERENCES Students (Student_ID),
FOREIGN KEY (Staff_ID) REFERENCES Staff (Staff_ID),
constraint ct1 check (Student_ID is null and Staff_ID is not null
                   or Student_ID is not null and Staff_ID is null)
);

约束ct1确保在给定的时间点只有一个处于活动状态。