这是正确的吗: 一旦实体随着时间的推移失去了属性不变性(可能是独立的,例如只有某个属性,然后又只有一个属性),正确规范化的唯一方法就是使用 6NF。
3NF 是 6NF 的特殊形式。但当时间方差进入游戏时,我无法想象 3NF。
一旦 实体失去了他们的 随时间变化的属性不变性,( 也许是独立的,例如只有一些 属性又只有一个 属性),唯一正确的方法 使用 6NF 进行归一化。
6NF 并不是“唯一”的方法。我怀疑 5NF 作为记录历史保存数据的方法比 6NF 更常用 - 通过将时间戳或时间范围作为键的一部分。 6NF 的优点是每次一个属性更改时不需要重复每个属性。这不是 5NF 所关心的一种冗余,因此根据 5NF,时变数据的 5NF 模型仍然是“正确的”——只是它可能比 6NF 保留更多的依赖关系。
Codd 还定义了标准化到 1NF 之外的目标,如下:
将关系集合从不需要的插入、更新和删除依赖性中解放出来。— E.F. Codd,“数据库关系模型的进一步规范化”,第 14 页。 34
- 随着新数据类型的引入,减少重组关系集合的需要,从而延长应用程序的生命周期。
- 使关系模型为用户提供更多信息。
- 使关系集合对查询统计数据保持中立,这些统计数据可能会随着时间的推移而改变。
根据该定义,
6NF 是时变数据唯一形式正确的标准化。 它还可以使数据比较变得更容易,当将历史记录与 5NF 和 6NF 表进行比较时,这一点会变得很清楚。 无论 5NF 还是 6NF,历史化总是在行级别完成。仅在 6NF 中,行的行为与列相同。对于 5NF,这意味着整个行及其所有列都被历史化,这已经违反了目标 1,因为冗余历史化数据可以被视为不期望的插入依赖项。根据已更改的数据量和表的大小,这可能会因冗余条目而导致大量空间浪费,并使差分时间计算变得更加困难,因为您现在必须比较 5NF 表中的整行而不是单个行(属性)6NF 表中的行。如果您想获取 5NF 时态表中单个属性的状态变化的实际时间,则必须手动修剪所有时态重述 (
A -> B -> [B -> B ->] C
)。使用 6NF 表,只有在您自己允许/引入的情况下才可以进行重述,并且可以通过触发器来避免重述,从而仅记录更改的数据,这有助于您更好地实现目标 2 和 3。如果您为此进行设计,您还可以获得通过将未知数设计为显式值,完全消除 NULL 值。
6NF 并非没有挑战,并且只能在框架内大规模完成,因为它会导致表的爆炸。如果您不想走 6NF 路线,并且只有某些属性具有较高的更新频率,则仅将它们从较大的 5NF 表移至它们自己的 6NF 表,然后通过外键将它们重新加入是有意义的以避免过度冗余的数据历史记录。但随着对数据及其历史记录的需求随着时间的推移而变化,可能需要进行另一次此类重组,并且目标 4 可能会一次又一次地失败,直到所有时变数据最终移动到单独的 6NF 表中。