规范化:将年份之类的静态数值拆分到他们自己的表中是否被认为是合规的?

sto*_*fin 16 normalization

我正在与另一位数据库设计人员就规范化进行有趣的讨论。在这个例子中,我们有一个 GameTitles 表,每条记录都必须包含游戏发布的年份。他说 2NF 要求所有内容都必须规范化,因此,要符合要求,年份字段应拆分为一个 ReleaseYears 表,该表具有自己的主键,由 GameTitles 表引用。我说它应该保留为 GameTitles 表本身的一个字段。

我对此的论点是,一年只是一个非原始数值,本质上是静态的(即,2011 年将始终是 2011 年)。因此,它充当自己的标识符,不需要引用它,因为它就是它。这也引入了额外的维护,因为您现在必须向表中添加新的一年才能引用它。如果您使用大范围的年份预先填充该表,那么您会有额外的记录,这些记录可能根本没有对它们的引用。这也增加了数据库大小,因为您现在有一个额外的表、记录开销和年份本身的额外主键。如果您将年份作为 GameTitles 表中的一个字段,则可以消除所有这些额外的维护和开销。

对此有何想法?

编辑:打算在 StackOverflow 上发布这个。有人可以投票删除此内容或将其标记以引起注意吗?

Mik*_*ll' 14

另一个数据库设计者是完全错误的,但你的推理也是错误的。假设您从这个表开始,它有一个候选键“game_title”。

Table: game_titles

game_title                      year_first_released
--
The first game                  1998
The second game                 1999
Best game: the third one        2001
The fourth game                 2003
Forty-two, the end of games     2011
Run Code Online (Sandbox Code Playgroud)

您可以通过问自己这些问题来评估它是否属于 2NF。

Q:首先,是在1NF中吗?

答:是的,是的。

问:什么是主要属性(作为候选键一部分的属性)?

A:“game_title”是唯一的主要属性。

问:什么是非主属性?

A:“year_first_released”是唯一的。

问:“year_first_released”在功能上是依赖于整个“game_title”,还是仅依赖于其中的一部分?

A:唯一的候选键“game_title”是一列;它甚至没有零件。所以“year_first_released”在功能上依赖于整个“game_title”。

瞧。你已经找到了 2NF。

您可以通过首先询问它是否在 1NF 中,然后回答这个问题来切掉一些正式术语。

问:是否有复合候选键?

答:没有。

瞧。你又找到了 2NF。

根据定义,对于违反 2NF 的表,它必须至少有一个包含多于一列的候选键。

以下是你拒绝朋友意见的理由。

  • 年只是一个非原始数值。
  • 一年本质上是静态的。
  • 一年作为它自己的标识符。
  • 年表介绍了额外的维护。
  • 年份表可能有未引用的额外行。
  • 年份表会增加数据库的大小。

这些原因都与表是否在 2NF 中没有任何关系。

在设计数据库时,考虑维护问题、数据库大小、未引用的行、范围约束等并没有错。将这些事情称为规范化是错误的。

哦,还有我上面提供的那个两列表——它是 5NF。

  • 做得很好。我很想发布一个答案,只说你的第一句话......“另一个数据库设计者完全错了”,你已经很好地说明了原因。 (2认同)

nvo*_*gel 5

为任何属性创建单独的表与规范化无关。2NF、3NF、BCNF、4NF、5NF 都与消除非密钥依赖有关。如果您删除新表的任何单个属性并将其替换为外键属性,则表中的依赖关系在逻辑上将与以前相同 - 因此表的修订版本不会比它更多或更少规范化以前是。


a_h*_*ame 5

从我的角度来看,单独的年份表只有在“发布年份”不是日历年时才有意义,但例如可能跨越多个日历年的财政年度(例如从 10 月到 10 月)。

然后该表将保存财政年度的定义(实际开始和结束日期)