将用户的宗教信息存储在“用户表”中时,如果你向下看一列,你会多次看到“基督徒”,多次看到“穆斯林”等等,认为是正常形式的失败?哪种形式?
我看待它的方式:
1nf:没有重复的列。
2nf:没有连锁的主键,因此不适用。
3nf:不依赖于非密钥属性。
以这种方式存储用户宗教似乎没有失败任何正常形式,但似乎非常低效。评论
答案 0 :(得分:6)
您的设计支持所有常规表单。您的属性具有字符串值很好。数据类型的大小与规范化无关。
规范化的目标不是物理存储效率 - 目标是防止异常。并支持逻辑效率,即仅存储给定事实一次。在这种情况下,给定行上的用户是基督徒的事实。
答案 1 :(得分:4)
以这种方式存储列的主要缺点是存储空间随着行数的增加而增加。
如果您有一组固定的选择,而不是字符列,则可以使用ENUM()
,这些选择很少(如果有的话)会发生变化,并且仍然可以避免创建一个宗教选项的附加表,一把外键。但是,如果选择不稳定,则规范化规则更倾向于使用用户表中的外键将选项放入自己的表中。
除了存储空间之外还有其他优点可以将它们保存在另一个表中。修改它们很容易。要将Christian
更改为Christianity
,您可以在宗教信息表中进行一次更改,而不是进行潜在的代价(如果您有很多行且宗教信息未编入索引)
UPDATE users SET religion='Christianity' WHERE religion='Christian'
...你可以做得更简单,更便宜
UPDATE religions SET name='Christianity' WHERE id=123
当然,您还可以通过键入宗教信息表来强制执行数据完整性。无法插入拼写错误的Christain
等无效值。
答案 2 :(得分:1)
我假设有一个有效宗教的清单;如果您刚刚让用户输入自己的字符串,那么您必须将其存储在用户表中,这一切都没有用。
假设宗教存放在他们自己的表中。如果您遵循完善的惯例,则此表将具有一个整数的主键,并且对其他表(例如用户表)中的表中的条目的所有引用都将是外键。存储宗教的字符串方法不违反任何正常形式(因为宗教的名称是宗教表的候选键),但它确实违反了不使用字符串作为键的做法。
(这是关系代数的理论和实践之间的一个有趣的区别。理论上,字符串与整数没有区别;它们都是原子数学值。在实践中,字符串有很多开销导致程序员不要将它们用作钥匙。)
当然,还有其他方法(例如某些RDBMS的ENUM)存储可能值的列表,每个值都有各自的优缺点。
答案 3 :(得分:0)
你的正常形式有点不对劲。第二种正常形式是行的其余部分取决于“整个键”。第三种正常形式是该行的其余部分取决于“只有关键”。 (所以帮助我Codd)。
不,您所描述的情况并未违反前三种常规表格中的任何一种。 (根据其他因素,可能会违反第六种情况。)
答案 4 :(得分:0)
这种方法有一些缺点(与使用外键相比),您需要确保自己可以使用。 1 - 浪费存储。 2 - 宗教信仰查询速度较慢 3 - 有人可能会在那里放置不匹配的数据,例如手动插入“Jedi”或您可能认为不正确的内容 4 - 没有办法列出可能的宗教信仰(例如,如果你的桌子中没有某个宗教信仰,例如琐罗亚斯德教),但你仍然希望它是一个有效的可能性 5 - 不正确的大写可能会导致问题 6 - 字符串周围的空白区域可能会导致问题
这种技术的主要优点是数据更快拔出(没有加入桌子),人类阅读也更快。