历史表和2nf

时间:2011-09-30 18:10:33

标签: database-design relational-database

用户表和组用户表是历史表(它们不能移动到存档表,因为这会弄乱与这些表相关的外键。如果组用户发帖并离开组,则帖子应该仍然存在等)

用户

用户名
开始日期
键(用户名,开始日期)

群组用户

组名

开始日期
小组开始日期
主键(组名,用户名,组开始日期)
外键(用户名,开始日期)

根据2NF,任何非关键字段都不能成为关键字子集的事实。在这种情况下,Username是组合键的一部分,Start Date是关于Username的事实,因此该表不在2NF中。

那么修复方法是将开始日期作为密钥的一部分包括在内吗?

2 个答案:

答案 0 :(得分:2)

  

开始日期是关于用户名

的事实

不是不是。模型中的用户名无法确定开始日期,因为(用户名,开始日期)是一个键 - 需要用户名和开始日期来识别用户表中的行。

答案 1 :(得分:1)

群组用户的PK可以说是不正确的,因为需要组合UserName和StartDate来唯一地标识用户。因此,如果'John'(第一个)加入2011-09-01而'John'(第二个)加入2011-09-10,则您的Group Users PK会阻止他们加入同一个组。您的组用户PK应包括用户名和开始日期,因为此组合是唯一标识用户的内容。

这就是人们使用“ID”列的原因;如果您有Users.ID列,那么您将在组用户的FK中使用该简单键。在其他表中本身用作外键的复合主键往往会出现问题(例如此类情况),而ID列等代理则会使DB设计更简单。

您可能也应该有一个Group表,Group Users.Group Name应该是该表的FK。有一点令人惊讶的是,Group Users表中和Users表中都没有“取消订阅日期”。或者您可能更喜欢“当前订阅”的标记,但通常日期也很有用。