我偶然发现了一个我不擅长的数据库设计问题,而我的首选 DBA 大师正在进行消防演习。
本质上,我有一个包含以下主键的表(为简洁起见,PK):
child_id integer
parent_id integer
date datetime
Run Code Online (Sandbox Code Playgroud)
child_id
和parent_id
是实体表的外键。“子”表本身也包含一个到“父”表的外键,而且,每个表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
Run Code Online (Sandbox Code Playgroud)
瞧,当我以自然的方式将这些人连接在一起时,我恢复了原始表。这是我的理解,使这个 5NF。
然而,现在我意识到有一个隐藏的商业规则。
通常,与给定关联的日期child_id
必须是与相应parent_id
. 您可以看到第一个表强制执行此规则。
我的分解不强制执行规则,因为您可以自由添加到表 1,直到日期变得太大。
这使我来到这里,有以下问题:
这是分解5NF吗?虽然我会说它允许插入异常,但它似乎也遵循 Wiki 示例,该示例本身遵循本指南。短语(强调我的)“我们可以从由三种不同记录类型组成的规范化形式重建所有真实事实”给了我特别的停顿,因为无论我注入多少垃圾Table_1
,自然连接仍然会忽略它。
假设我不喜欢这种分解(我不喜欢)。我坦率地承认,实际的解决方案是让表格和代码保持原样。但是,从理论上讲,有没有办法分解和/或添加约束,以便我摆脱第一个表并保留我的业务规则?
schema normalization database-design best-practices relational-theory