时间数据库建模和规范化

4

在一个时间数据库中,日期应该存储在一张表还是两张表中?如果只有一张表,是否违反了规范化?

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

DATE1和DATE2列表示在DATE1和DATE2之间,INFO1和INFO2是正确的。如果DATE < TODAY,则这些事实被弃用,不应再显示在用户界面中,但为了历史目的,它们不应被删除。例如,INFO11和INFO21现在已经被弃用。

我应该拆分这个表吗?我应该在表中存储状态(弃用或当前)吗?

进一步澄清问题,"弃用"是业务使用的术语,如果您喜欢"非当前",问题并不是语义上的,也不涉及SQL查询,我只想知道哪种设计违反或最适合规范化规则(我知道规范化并不总是可取的,这也不是我的问题)。


4
请在您的问题中增加更多的背景信息。 - Vinko Vrsalovic
3个回答

4

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

这取决于您想遵循哪一组规范化规则。

最有可能违反规范形式的第一个问题,在Date's book中违反了first NF,即在保存“当前”信息的行中的结束日期(忽略未来日期信息的可能性):如果将该属性设为可空,则违反了1NF。

违反BCNF的情况很明显是由于您选择的键而引起的(在非时间数据库设计中也是如此-时间方面在这里没有区别)。关于“键的选择”:如果您使用单独的开始和结束日期(并且SQL几乎没有其他选择),那么最好声明两个键:一个包括开始日期,另一个包括结束日期。
另一个设计问题是多个数据列。在“时态数据和关系模型”中广泛讨论了这个问题:如果INFO1和INFO2可以相互独立地更改,则最好将表分解为仅保存一个属性,以避免可能会发生的“行数爆炸”,否则每次行中的单个属性更改时都必须创建新的完整行。在这种情况下,您提供的设计构成了第六范式的违规,如“时态数据和关系模型”中所定义的。

2

规范化是关系数据库的一个概念,不一定适用于时间数据库。这并不是说你不能在关系数据库中存储时间数据,你当然可以。

但如果你要进行时间数据库设计,那么应该应用时间规范化的概念而非关系规范化。


1
嗯,其实没有什么选择,因为组织机构都使用关系型数据库。我看不出来"Temporal Normalization"是什么意思,你有链接吗? - programmernovice

2
您没有说明这些日期的含义。它们是指(a)陈述事实在真实生活中成立的时间段,还是(b)数据库持有者认为该陈述事实为真的时间段?如果是(b),那我不会这样做。当更新完成时,立即将更新行移动到归档表/日志中。如果是(a),那么以下声明是可疑的:
"这些事实已被弃用,不应在用户界面中显示"
如果一个事实不再需要在用户界面中显示,那么它就不需要再在数据库中存在了。保留这些事实只会达到一件事:恶化其余所有内容的整体性能。
如果您确实需要这些历史事实来满足您的要求,则很有可能您所谓的“弃用事实”仍然与业务密切相关,因此根本不是“弃用”的。假设出于这个原因,在您的数据库中有很少的“真正弃用的”事实,那么您的设计是好的。只需定期从操作数据库中删除“真正弃用的事实”,并保持其数量较少即可。
(附言)说您的设计很好,并不意味着您不会遇到任何问题。 SQL极不适合优雅地处理这种信息。《时间数据和关系模型》是这个主题的优秀论著。另一本书,Snodgrass的书也经常被赞扬,尽管不是我的口味。那本书是一个食谱,包含了处理这些SQL问题的方法,正如下面关于这本书的对话所证明的那样:
(Q)“我为什么要读这个?” (A) “因为你要的触发器在第135页。”

事实已被弃用,这意味着它不再像你搬到另一个城市那样真实,但政府仍将保留你过去居住地的历史记录。 - programmernovice
“Deprecated”是业界使用的术语,如果您不喜欢使用“当前版本”,那么问题并非语义上的。也不是关于SQL查询的问题。我想知道哪种设计违反了规范化原则。 - programmernovice

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接