我偶然发现了一个数据库设计问题,而这个数据库设计问题超出了我的能力范围,而我的DBA专家也开始进行防火训练。
本质上,我有一个带有以下主键的表(为简洁起见,PK):
child_id integer
parent_id integer
date datetime
child_id
并且parent_id
是实体表的外键。“子”表本身还包含“父”表的外键,并且lo child_id
始终引用与parent_id
上表所期望的相同的外键。实际上,事实证明,还有一些额外的代码可以使两者保持同步。
这使这位热情洋溢的标准化新手说:“我应该删除冗余!”
我分解为以下内容:
Table_1 PK:
child_id integer
date datetime
Table_2 PK:
parent_id integer
date datetime
Table_3: (already exists)
child_id integer PRIMARY KEY
parent_id integer FOREIGN KEY
而且,当我自然地将这些人加入一起时,我将恢复原始表。据我了解,制造出了5NF。
但是,现在我意识到存在隐藏的业务规则。
通常,与给定日期关联的日期child_id
必须是与对应日期关联的日期的子集parent_id
。您可以看到第一个表强制执行此规则。
我的分解不会强制执行该规则,因为您可以自由地将其添加到表1中,直到日期变得太大为止。
这将我引向以下问题:
这是5NF分解吗?虽然我说它允许插入异常,但它似乎也遵循Wiki示例,该示例本身遵循本指南。短语(强调我)“我们可以从由三种不同的记录类型组成的规范化形式中重构所有真实事实”,这给了我一个特殊的停顿,因为无论我注入多少垃圾
Table_1
,自然连接仍然会忽略它。假设我不喜欢这种分解(我不喜欢)。我自由地承认,实际的解决方案是保留表和代码不变。但是,从理论上讲,是否有一种方法可以分解和/或添加约束,以使我摆脱第一个表并保留我的业务规则?