我正在与另一位数据库设计人员就规范化进行有趣的讨论。在这个例子中,我们有一个 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。
为任何属性创建单独的表与规范化无关。2NF、3NF、BCNF、4NF、5NF 都与消除非密钥依赖有关。如果您删除新表的任何单个属性并将其替换为外键属性,则表中的依赖关系在逻辑上将与以前相同 - 因此表的修订版本不会比它更多或更少规范化以前是。
从我的角度来看,单独的年份表只有在“发布年份”不是日历年时才有意义,但例如可能跨越多个日历年的财政年度(例如从 10 月到 10 月)。
然后该表将保存财政年度的定义(实际开始和结束日期)