这是数据库设计中的常见问题,有 3 种最常见的处理方法(如果我们计算 EAV,则为 4 种):
三个单独的表,每种类型一个。
一张表 - 有很多列 - 其中一些将被允许有空值。数据库不容易处理完整性(哪些列组合将为 Null,哪些不是),通常由应用程序处理。这是@noa 的答案,它会导致代码稍微少一些,并且可能更容易提出一个工作(虽然不完美)的应用程序。
一个Member
表(这是超类型)和 3 个附加表,每个子类型一个。这允许您没有 Null,并根据组织类型强制使用哪些列。(这是您的选项 1)
您还可以org_type
在所有表中添加一列。这将意味着一个额外的UNIQUE
约束,Member (org_type, member_ID)
并且FOREIGN KEY
约束(来自每个子类型表)被更改为包含该org_type
列。像这样的东西:
CREATE TABLE Member
( MemberID
, Org_Type
, Name
, ...
, Role
, PRIMARY KEY (MemberID)
, UNIQUE KEY (Org_Type, MemberID)
, CHECK Org_Type IN (1, 2, 3)
) ;
CREATE TABLE Member_Type_1
( MemberID
, Org_Type
, Location
, PRIMARY KEY (MemberID)
, FOREIGN KEY (Org_Type, MemberID)
REFERENCES Member(Org_Type, MemberID)
, CHECK Org_Type = 1
) ;
and finally there's (your option 2) EAV:
- 根据维基百科,实体-属性-值模型是:
用于描述实体的数据模型,其中可用于描述它们的属性(属性、参数)的数量可能很大,但实际应用于给定实体的数量相对较少。在数学中,这个模型被称为稀疏矩阵。EAV 也称为对象-属性-值模型、垂直数据库模型和开放模式。
在关系数据库中不使用 EAV 的原因有很多,主要是因为数据类型和引用完整性方面的问题(不能轻易实施)、即使是简单的查询也难以编写(最终会编写很多连接)和效率。请参阅 Simon Righarts 在 DBA.SE 问题上的回答:此数据库结构有名称吗?
不过,在某些情况下它是一个有效的选择是有原因的,正如 Aaron Bertrand 的文章所解释的那样:EAV 到底有什么不好的地方?,尤其是当您有很多列时,甚至在您事先不知道需要哪些列时(客户定制)。如果您希望组织能够添加自定义列,那可能就是您的情况。
但是请注意,构建一个高效的 EAV 模型/应用程序并不容易。您实际上是在数据库中构建 RDBMS。