考虑下表:
+-------+-------+-------+-------+
| name |hobby1 |hobby2 |hobby3 |
+-------+-------+-------+-------+
| kris | ball | swim | dance |
| james | eat | sing | sleep |
| amy | swim | eat | watch |
+-------+-------+-------+-------+
爱好的类型没有优先权,因此所有的爱好都属于同一个域。也就是说,表格中的爱好可以在任何hobby#
列上移动。无论哪一列,特定的爱好都可以在任何列中。
此表违反了哪个数据库规范化规则?
Q值。是“任意顺序的爱好列表”吗?
一个。是。
Q值。表有主键吗?
一个。是的,假设密钥是名为AUTO_INCREMENT
的{{1}}列类型。
问题是列user_id
是否重复组。
Sidenote :这不是作业。这是一场辩论,始于问题SQL - match records from one table to another table based on several columns的评论。我相信这个问题是违反1NF的明显例子。
然而,另一个人认为我“已经堕落了1NF的谬误之一。”这个论点是基于文章{{的重复群体的模糊性“一节。 3}}
我不是写这个来羞辱他,我或任何人。我正在写这篇文章,因为我可能错了,而且我有一些东西显然是错过的,也许这个家伙并没有向我解释它。
答案 0 :(得分:10)
你说爱好属于同一个域,他们可以在列中移动。如果你的意思是,对于任何特定的name
,爱好列表是任意顺序而kriss可以像舞蹈,球,游泳,游泳,跳舞一样容易,那么我会说你有一个重复组和表违反了1NF。
另一方面,如果某个人的第一和第二爱好之间存在一些基本的语义差异,那么可能会有一个论据,即爱好不是重复群体而且表格可能在3NF(假设爱好列是FK到业余爱好者表)。我建议这个论点,如果存在的话,很弱。
要考虑的另一个因素是为什么正好有3个爱好以及是否有更多或更少的爱好是潜在的问题。这个因素对于归一化和设计灵活性来说并不重要。这就是我将爱好分成几行的一个原因,即使它们在语义上彼此不同。
答案 1 :(得分:6)
你的三个爱好表设计可能违反了我通常称之为原始1NF的精神(可能,原因是dportas和其他人提供的原因)。
然而,事实证明,找到[一套]正式且精确的“可衡量”标准是非常困难的,这些标准准确地表达了原始的“精神”。这就是你的另一个人试图解释的“重复群体的模糊性”。在这里强调“正式”,“精确”和“可衡量”。存在满足“形式”,“精确”和“可测量”(即客观可观察)的所有其他正规形式的定义。对于1NF来说,这很难(/不可能)。如果你想知道原因,试试这个:
你说问题是“这三个爱好专栏是否构成一个重复的小组”。用“是”回答这个问题,然后为你的答案提供严格的正式基础。
除了编号后缀之外,您不能只说“列名相同”。违反这一规则是客观上可观察/可衡量的,需要列举所有可能的后缀方法。
你不能只说“游泳,网球”同样可以成为“网球,游泳”,因为要知道这肯定需要检查桌子的外部谓词。如果那只是“人< name>有爱好< hobby1>并且还有< hobby2>”然后确实两者都同样有效(除了:由于封闭的世界假设,它实际上需要所有可能的爱好排列存在于表格中!!!)。但是,如果该外部谓词是“人< name>花费最多时间在< hobby1>上并且最少花费在< hobby2>”上,那么“游泳,网球”可以 NOT 同样很好“网球,游泳”。但是你如何对表格目标的外部谓词做出这样的解释(对于所有可能的预测)???
等。等
答案 2 :(得分:5)
这显然“看起来”像是设计错误。
简单地存储和检索此数据时,这不是设计错误。您只需要3个爱好,并且您不打算以任何其他方式使用此数据。
让我们考虑一下这种关系:
然后这个表似乎设计得很好,虽然1NF惯例得到尊重,但命名可能会“糟透了”。
在不加选择地存放爱好的情况下,如果不是所有我现在都能想到的情况,这显然是错误的。您的表有重复的行,违反了1NF原则。
当您需要为分页或其他任何实际原因对结果进行排序时,不要考虑SQL请求从此表访问数据的效率降低。
让我们考虑当您的数据库被其他开发人员或团队使用时,处理您的数据所需的工作:
你基本上会产生沮丧,愤怒和仇恨,而且力量会被打扰。
答案 3 :(得分:3)
那么,
关键在于,只要所有hobby1,hobby2和hobby3值都不为空, AND名称是唯一的,就可以将此表或多或少视为违反1NF规则(参见{ {3}} ...)
但是每个人都有3个爱好吗?当然不是!不要忘记数据库基本上应该用数据来表示现实!所以,除了所有理论之外,人们不能说每个人都有3个爱好,除非...我们的表是用来保存与people that have three hobbies without any preference between them
相关的数据!
这就是说,假设我们在一般情况下,正确的模型可能是
+------------+-------+
| id_person |name |
+------------+-------+
为人(不要忘记独特的钥匙。我不认为'名字'是一个好的
+------------+-------+
| id_hobby |name |
+------------+-------+
兴趣爱好。 id_hobby键在理论上不是强制性的,因为爱好名称可以是关键......
+------------+-----------+
| id_person |id_hobby |
+------------+-----------+
关于人与爱好之间的联系,作为人与爱好之间存在的多对多关系的物理表征。
我的建议是基本的,并且满足理论。它可以通过多种方式得到改善......
答案 4 :(得分:3)
在不知道存在哪些键以及表应该满足哪些依赖关系的情况下,无法确定它满足哪种Normal Form。我们所能做的就是根据您的属性名称进行猜测。
桌子上有钥匙吗?假设为了示例,Name是候选键。如果每个元组的每个其他属性只允许一个值(这意味着没有属性可以为null),那么该表至少为First Normal Form。
答案 5 :(得分:2)
如果表中的任何列接受空值,则表违反第一个普通表单。假设没有空值,@ dportas已经提供了正确的答案。
答案 6 :(得分:1)
该表不违反第一范式。
第一范式对同一类型的多个列没有任何禁止。只要它们有不同的列名,就可以了。
禁止“重复组”涉及嵌套记录 - 这种结构在分层数据库中很常见,但在关系数据库中通常不可能。
使用重复组的表格看起来像这样:
+-------+--------+
| name |hobbies |
+-------+--------+
| kris |+-----+ |
| ||ball | |
| |+-----+ |
| ||swim | |
| |+-----+ |
| ||dance| |
| |+-----+ |
+-------+--------+
| james |+-----+ |
| ||eat | |
| |+-----+ |
| ||sing | |
| |+-----+ |
| ||sleep| |
| |+-----+ |
+-------+--------+
| amy |+-----+ |
| ||swim | |
| |+-----+ |
| ||eat | |
| |+-----+ |
| ||watch| |
| |+-----+ |
+-------+--------+
在符合 1NF 的表中,所有值都可以通过表名、主键和列名来定位。但是对于需要进一步导航的重复组,这是不可能的。