我有一个可能包含数千个实体表的动态数据模型,我们称它们为 E1、E2、...,或者通常为 EX。
还有少量的实用程序表,其中包含可能附加到这些实体的数据,例如审计表或“附加文档”表,我们称它们为 U1、U2、...,或通常为 UX。
每对 EX-UX 的关系是一对多(例如 E1 中的每个实例可能有多个附加文档,但每个文档仅附加到任何 EX 中的一个实例)。
基本问题是每个 UX 都包含引用不同表 EX 的行。
有几种方法可以对这种关系进行建模:
链接表解决方案
为每对 EX/UX 创建一个链接表。例如:
E1_U1 (
E1_ID FK TO E1
U1_ID FK TO U1
)
- 优点:干净。EX型号不变
- 缺点:表数量激增,我们也可以为每个实体创建每个实用程序表的实例。如果我需要反向查找,例如显示 EX 中的实例,它被 U1 中的某个实例引用,我需要搜索所有链接表 EX_U1。
实体表解决方案
创建一个新表 ENTITY,其中包含一列 ENTITY_ID,它是任何 EX 中每一行的唯一 ID。在此模型中,将每个 EX 的主键替换为 ENTITY_ID 是有意义的。
ENTITY (
ENTITY_ID PK
)
E1 (
ENTITY_ID PK, FK TO ENTITY
...
)
U1 (
U1_ID PK
ENTITY_ID FK TO ENTITY
...
)
- 优点:我想这是建模继承的标准方法
- 缺点:显着改变了数据模型和应用程序逻辑。只有通过在所有 EX 中搜索正确的 ENTITY_ID 才能进行反向查找。
“键入的外键”解决方案
为每个 UX 提供两列作为“键入的外键”:ETABLE_ID 和 ETABLE_ROW_ID。ETABLE_ID 引用该表(即哪个EX),ETABLE_ROW_ID 是该表中的行。
在我的模型中这是可能的,因为
- 我已经在应用程序逻辑中保留了我的实体表的元模型,因此 ETABLE_ID 很容易获得
- ETABLE_ROW_ID 保证所有 E 的类型相同
U1 ( U1_ID PK ETABLE_ID FK TO ETABLE ETABLE_ROW_ID ... )
- 优点:EX的型号没有变化。反向查找可以很容易地在应用程序逻辑中实现。
- 缺点:问题显然是我们不能对 ETABLE_ROW_ID 应用外键约束。
虽然它不是干净的关系设计,但我仍然赞成最后一种解决方案,因为它具有实际优势。我可以在应用程序逻辑中建模丢失的引用完整性。
这个问题的首选解决方案是什么?有什么经验/建议吗?