时态数据库建模和规范化

时间:2009-10-03 21:05:22

标签: database database-design temporal-database

临时数据库的日期应该存储在一个还是两个表中?如果这不违反正常化?

PERSON1 DATE11 DATE21 INFO11 INFO21 DEPRECATED
PERSON2 DATE21 DATE22 INFO21 INFO22 CURRENT
PERSON1 DATE31 DATE32 INFO31 INFO32 CURRENT

DATE1和DATE2列表示INFATE和INFO2在DATE1和DATE2之间的时间段内为真。如果DATE<今天,事实已被弃用,不应再在用户界面中显示,但出于历史目的不应删除它们。例如,现在不推荐使用INFO11和INFO21。

我应该拆分这张桌子吗?我应该将状态(不建议使用还是当前)存储在表中?

为了进一步澄清这个问题,Deprecated是商业使用的术语,如果你更喜欢“不是最新的”,问题不是语义问题,也不是关于sql查询,我只是想知道哪个设计违反或最好适合规范化规则(我知道规范化并不总是可行的方式,这也不是我的问题。)

3 个答案:

答案 0 :(得分:4)

“我想知道哪个设计违反了规范化规则”

取决于您希望使用哪组规范化规则。

第一个也是最有可能违反正常表单的行为,并且在Date's book中违反了first NF,是您在行中保存“当前”信息的结束日期(对未来日期信息的可能性):如果您将该属性设为可空,则违反1NF。

由于您选择了密钥,很明显会发生违反BCNF的情况(非时间数据库设计也是如此 - 时间方面在这里没有区别)。 Wrt“选择键”:如果你使用单独的开始日期和结束日期(并且SQL类型让你别无选择),那么很可能你应该声明两个键:一个包含开始日期,一个包括结束日期。

另一个设计问题是多个数据列。在“时态数据和关系模型”中对此问题进行了大量讨论:如果INFO1和INFO2可以彼此独立地更改,那么将表分解为仅保留一个属性可能更好,以避免“爆炸”行计数“如果必须在每次行中的单个属性更改时创建新的完整行,则可能会出现这种情况。在这种情况下,您提供的设计构成违反SIXTH正常形式,因为(正常形式)在“时态数据和关系模型”中定义。

答案 1 :(得分:2)

规范化是一种关系数据库概念 - 它不适用于时态数据库。这并不是说你不能在关系数据库中存储时态数据。你绝对可以。

但是如果你要使用时态数据库设计,则应用时态规范化的概念而不是关系规范化。

答案 2 :(得分:2)

您尚未说明日期的含义。它们是指(a)在现实生活中所述事实是真实的时期,还是(b)数据库持有人所声称的事实被认为是真实的期间?如果(b),那么我永远不会这样做。更新完成后,立即将更新的行移动到存档表/日志。如果(a),那么以下陈述是有问题的:

“事实已被弃用,不应再在用户界面中显示”

如果事实不再“需要在用户界面中显示”,那么它也不再需要在数据库中。保持这样的事实只能实现一件事:所有其他事情的总体表现都会恶化。

如果您确实需要这些历史事实陈述以满足您的要求,那么您所谓的“弃用事实”可能仍与业务非常相关,因此根本不会“弃用”。由于这个原因,您的数据库中很少有“真正弃用”的事实,您的设计很好。通过定期将其从运营数据库中删除,只需保留“真正弃用的事实”的数量。

(PS)要说你的设计很好,并不意味着你不会遇到任何问题。 SQL非常不适合优雅地处理这种信息。 “时间数据和关系模型”是该主题的优秀治疗方法。另一本来自斯诺德格拉斯的书虽然不是我,但也经常受到赞扬。那个是一本食谱,里面有一些用于处理SQL中这些问题的方法,正如下面关于本书的SO对此书的论证所证明的那样:

(问)“为什么我会读到这个?” (A)“因为你要求的触发器是在第135页。”