【问题标题】:Database design - two foreign keys but one is always null and the other is always not null数据库设计 - 两个外键,但一个始终为空,另一个始终不为空
【发布时间】:2021-02-24 02:34:56
【问题描述】:

我有三个表: propertypersoncompany。一个财产只能属于个人或公司。一个人或一个公司可以拥有多个财产。 我当前的数据库设计是在property 表中包含两个外键-person_idcompany_id,其中一个始终为空,另一个不为空。我只是想知道在这种情况下是否有更好的方法来设计数据库?

CREATE TABLE person(
   person_id int NOT NULL PRIMARY KEY,
   name varchar(255)
);

CREATE TABLE company(
   company_id int NOT NULL PRIMARY KEY,
   name varchar(255)
);

CREATE TABLE property(
   property_id int NOT NULL PRIMARY KEY,
   name varchar(255),
   person_id REFERENCES person,
   company_id REFERENCES company
);

【问题讨论】:

  • 我很想说所有财产都归组织所有。其中一些组织可能是个人。
  • @Strawberry 这可能不是一个好的设计。如果你这样做,你会假设公司和个人具有相同的属性,但在实际场景中他们没有。您的设计适合的另一种情况可能是:例如,如果这两个表是学生和教师,您可以简单地创建一个人员表并添加一个 person_type 属性来指定一个人是学生还是教师。
  • 你使用的是 MySQL 还是 Postgresql?
  • 没有。不完全是这样。在这种情况下,用户是组织的成员。

标签: mysql sql database postgresql database-design


【解决方案1】:

创建额外的表CHECK约束:

CREATE TABLE property(
   property_id int NOT NULL PRIMARY KEY,
   name varchar(255),
   person_id REFERENCES person,
   company_id REFERENCES company,
   CHECK (person_id IS NULL + company_id IS NULL = 1)
);

这将禁止错误值(NULL 或 NOT NULL)。

附言。两个引用存在本身是合法且安全的。

【讨论】:

  • PostgreSQL 语法的最后一行:CHECK (person_id IS NULL AND company_id IS NOT NULL OR person_id IS NOT NULL AND company_id IS NULL = TRUE)
猜你喜欢
  • 1970-01-01
  • 2018-02-10
  • 2019-07-06
  • 2014-10-04
  • 1970-01-01
  • 2018-10-01
  • 2015-01-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多