具有两个参考的主键

时间:2019-05-16 17:15:05

标签: mysql sql postgresql

我希望我的关系表“ In”具有一个外键SSN,它引用两个表,但是SSN仅在这两个表之一中。 当我这样做时:

ALTER TABLE "In"
ADD CONSTRAINT in_C1 FOREIGN KEY (SSN) REFERENCES patient(SSN),
ADD CONSTRAINT in_C2 FOREIGN KEY (SSN) REFERENCES patientWithDoD(SSN)

然后,SSN必须在表Patient和PatientWithDoD中。 SSN应该在两个表之一中,但不能同时在两个表中。我该怎么办?

2 个答案:

答案 0 :(得分:1)

当列具有非空值时,将检查并验证所有相关的外键约束。如果检查失败,则无法插入或更新该行。

如果您有两个FK,并且只想强制执行其中一个,那么您将需要:

  • 创建两个单独的可为空的列,每个FK对应一个,并且
  • 添加CHECK约束以强制执行一个约束,只有一个约束不为null。

例如:

create table "In" (
  id int primary key not null,
  ssn int, -- nullable
  ssn_dod int, -- nullable
  constraint fk1 foreign key (ssn) references patient (ssn),
  constraint fk2 foreign key (ssn_dod) references patientwithdod (ssn),
  constraint chk1 check (ssn is null and ssn_dod is not null or
                         ssn is not null and ssn_dod is null)
);

不幸的是,MySQL最近才开始强制实施CHECK约束(如果我还记得的话,是MySQL 8.0.3)。如果您使用的是旧版本的MySQL,那么您会很不走运:MySQL将允许您编写并保存约束,但不会强制执行。

答案 1 :(得分:0)

我知道您在PatientWithDoD表上没有SSN属性。要引用外键,您必须将此属性添加到此表中。

您建议您,仅将必要的属性添加到患者表。例如:ssn,姓名,姓氏等。

然后不要将名称,姓氏和其他患者属性添加到PatientWithDod表中。您只能使用ssn来引用剩余的患者数据。因此,添加ssn指向Patient.ssn

的外键

这种结构会更好,您不必引用patienWithDod表。