我正在与另一位数据库设计师就规范化问题进行有趣的讨论。在这个例子中,我们有一个GameTitles表,每个记录必须包含游戏发布的年份。他说2NF强制要求所有内容都必须标准化,因此,为了符合要求,应将year字段拆分为具有自己的主键的ReleaseYears表,该主键由GameTitles表引用。我说它应该保留在GameTitles表本身的一个字段上。
我的论点是,一年只是一个非原始的数值,就其本质而言是静态的(即,2011年总是2011年)。因此,它作为自己的标识符,不需要任何引用它,因为它就是它。这还引入了额外的维护,因为您现在必须在表中添加新年才引用它。如果您在很长一段时间内预填充表格,那么您将拥有可能根本不会引用它们的额外记录。这也增加了数据库大小,因为您现在有一个额外的表,记录开销以及年份本身的额外主键。如果您将年份保留为GameTitles表中的字段,则可以消除所有这些额外的维护和开销。
对此的想法?
答案 0 :(得分:5)
人们可以很容易地查找2NF的定义 - 并且“归一化的一切”不是它。如果用一个新表(id,c)的构造替换单个列c(此处为年份),其中id是唯一的并且在前一个表中用c替换c(代理键任何人?),则无法满足更多任何方式的规范化规则的逻辑约束(证据留给读者 - 来自c的所有函数依赖关系与具有替换列id的那些关系是1:1)。如果有人提出这样的话,他就不明白正常化了。
答案 1 :(得分:3)
为任何属性创建单独的表与规范化无关。 2NF,3NF,BCNF,4NF,5NF都与消除非密钥依赖关系有关。如果删除任何单个属性到新表并将其替换为外键属性,那么表中的依赖关系在逻辑上将与以前相同 - 因此表的修订版本不会比它更多或更少标准化在此之前。
答案 2 :(得分:2)
正如其他人所指出的那样,其他数据库设计师完全错了,但你的推理也是错误的。假设您从这个具有单个候选键“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
您可以通过问自己这些问题来评估它是否在2NF中。
问:首先,is it in 1NF?
<答:是的,是的。问:什么是主要属性(属于候选键的属性)?
答:“game_title”是唯一的主要属性。
问:什么是非素数属性?
答:“year_first_released”是唯一一个。
问:“year_first_released”在功能上是依赖于整个“game_title”,还是仅仅依赖于它的一部分?
答:唯一的候选键“game_title”是一列;它甚至没有零件。所以“year_first_released”在功能上依赖于整个“game_title”。
瞧。你找到了2NF。
您可以首先询问是否在1NF中,然后回答这个问题来切断一些正式条款。
问:是否有复合候选键?
答:没有。
瞧。你又找到了2NF。
根据定义,对于违反2NF的表,它必须至少有一个具有多个列的候选键。
以下是拒绝朋友意见的原因。
这些原因都与表格是否在2NF中有任何关系。
在设计数据库时,考虑维护问题,数据库大小,未引用的行,范围约束等并没有错。将那些事情称为规范化是错误的。
哦,我上面提供的那个双列表 - 它在5NF。
答案 3 :(得分:1)
我倾向于将逻辑和物理数据库设计分开。
在我的逻辑设计中,年份列的规范化形式将是年表。
然而,在我的物理设计中,我会对其进行去标准化。除非您可以演示通过规范化或业务原因(例如跟踪更改)解决的数据存储或检索异常,否则我会将Year列留在表中。
现在,如果你有类似于ProductName VarChar (255)
的东西那么由于过多的好处(性能提升,进一步规范化等)而拥有自己的桌子会很好,但我不这样做特别是在这种情况下看到这些好处。
以下是跟踪变更的业务需求的极端示例:
我有一个表格设计存储了一个人的性别。所以有点标志 - 女性为1,男性为0应该可以接受,对吧?在此特定应用中,跟踪性别变化是合法的要求。性别标志不仅得到了自己的表格,而且立即与员工建立了多对多的关系。