【问题标题】:Which normal form does this table violate?该表违反了哪种范式?
【发布时间】:2011-11-29 19:00:59
【问题描述】:

考虑这张表:

   +-------+-------+-------+-------+  
   | name  |hobby1 |hobby2 |hobby3 |  
   +-------+-------+-------+-------+   
   | kris  | ball  | swim  | dance |  
   | james | eat   | sing  | sleep |  
   | amy   | swim  | eat   | watch |  
   +-------+-------+-------+-------+

兴趣类型没有优先级,所有兴趣都属于同一个领域。也就是说,表格中的爱好可以移动到任何hobby# 列上。不管在哪一栏,一个特定的爱好都可以在任何一栏。

此表违反了哪个数据库规范化规则?


编辑

问。 “爱好列表 [...] 是任意顺序的”?

A.是的。

问。表有主键吗?

A.是的,假设键是一个名为user_idAUTO_INCREMENT 列类型。

问题是hobby# 的列是否是重复组。


旁注:这不是家庭作业。这是一场辩论,始于问题SQL - match records from one table to another table based on several columns 的cmets。我相信这个问题是违反 1NF 的一个明显例子。

但是,另一个人认为我“已经陷入了 1NF 的谬误之一。”该论点基于文章 @987654322 的“重复组的歧义”部分@。

我写这篇文章不是为了羞辱他、我或任何人。我写这篇文章是因为我可能错了,而且我显然遗漏了一些东西,也许这个人对我的解释不够好。

【问题讨论】:

  • 我不知道所有的技术术语,但对我来说,这违反了“如果有人有 4 个爱好怎么办?”规则。 :)
  • @JoeEnos 是的,这也是它对我的作用。这正是 1NF 处理的问题。
  • 这简直是邪恶的......一代又一代人将不得不忍受一生中只允许有 3 种爱好的痛苦......谁同时需要 3 种以上的爱好?谁需要超过 640kb?
  • 如果一个人有 4 个爱好,那么表格不能存储第 4 个。这不是违反 1NF - 它只是意味着您的设计有限制。如果要求只存储三个爱好,那么这对您来说可能不是问题。
  • 我虽然你说过,“问题是 hobby# 列是否是重复组。”如果列可以为空,则违反 1NF,重复组的问题没有实际意义。

标签: database database-design relational-database database-schema database-normalization


【解决方案1】:

这显然“看起来”像一个设计错误。

简单地存储和检索这些数据并不是设计错误。您只需要其中的 3 个爱好,并且除了检索之外,您不打算以任何其他方式使用这些数据。

让我们考虑一下这种关系:

  • 爱好 1 是人一生中某个阶段的主要爱好(例如 18 岁之前)
  • Hobby2 是另一点的爱好 (19-30)
  • Hobby3 是她的另一个爱好。

那么这个表看起来绝对是精心设计的,虽然 1NF 约定得到尊重,但命名可以说是“烂透了”。

在不加选择地存储爱好的情况下,这在我现在能想到的大多数情况下显然是错误的。您的表有重复的行,这违反了 1NF 原则。

当您需要为分页或任何其他实际原因对结果进行排序时,我们不要考虑 SQL 请求访问该表中数据的效率降低。

让我们考虑一下当您的数据库将被其他开发人员或团队使用时处理您的数据所需的工作量:

  • 这里的数据是“分散的”。您必须查看多个列才能汇总相关数据。
  • 您仅限于 3 个爱好。
  • 您不能使用简单的规则来建立唯一性(每个用户只有一次相同的爱好)。

你基本上是在制造挫折、愤怒和仇恨,而原力被扰乱了。

【讨论】:

  • 基本上就像用“user” UNIQUE 创建 3 个 hobby# 表一样糟糕
【解决方案2】:

您说这些爱好属于同一个领域,并且它们可以在列中移动。如果你的意思是对于任何特定的name,爱好列表是任意顺序的,并且 kriss 可以像跳舞、球、游泳一样轻松地跳舞、游泳、跳舞,那么我会说你有一个重复组和该表违反了 1NF。

另一方面,如果某个人的第一个和第二个爱好之间存在一些基本的语义差异,那么可能有一个论据可以说这些爱好不是重复的组,并且表格可能是 3NF(假设爱好列是爱好表的 FK)。我会建议这个论点,如果它存在的话,是弱的。

另一个需要考虑的因素是为什么恰好有 3 个爱好,以及更多或更少的爱好是一个潜在的问题。这个因素对标准化很重要,而不是对设计的灵活性重要。这是我将爱好分成几行的原因之一,即使它们在语义上彼此不同。

【讨论】:

  • 是的,我的意思是“爱好列表是任意顺序的”
  • 说得好!你的答案很清楚。
  • @Shef:我认为使用“列表”一词会混淆这一点。 relvar 中的三个属性与列表中的三个值不是同一个概念。同上乔尔。
  • @onedaywhen 这就是那里的爱好,这个特定人的爱好列表,仅此而已。对该问题的 OP 的编辑显示了一个包含空值的表。这导致我们发现这些列包含一个爱好列表。
  • @Shef:如果是这种情况,那么您问题中的图片应该显示包含爱好列表的单列,而不是三列,每列显示似乎是标量值。
【解决方案3】:

嗯,

关键是,只要所有的 hobby1、hobby2 和 hobby3 值不为空,AND 名称是唯一的,这个表可以或多或少地被认为是遵守 1NF 规则(参见 @ 987654321@ ...)

但是每个人都有 3 个爱好吗?当然不是!不要忘记,数据库基本上应该保存数据作为现实的表示!所以,抛开所有的理论,不能说每个人都有 3 个爱好,除非……我们的表已经完成保存与 people that have three hobbies without any preference between them 相关的数据!

这就是说,假设我们在一般情况下,正确的模型可能是

+------------+-------+
| id_person  |name   |
+------------+-------+  

对于人(不要忘记唯一的关键。我不认为'name'是一个好的)

+------------+-------+
| id_hobby   |name   |
+------------+-------+ 

为了爱好。 id_hobby 键理论上不是强制性的,因为爱好名称可以是键...

+------------+-----------+
| id_person  |id_hobby   |
+------------+-----------+  

对于人和爱好之间的链接,作为存在于人和他们的爱好之间的多对多链接的物理表示。

我的建议是基本的,并且满足理论。它可以通过多种方式进行改进...

【讨论】:

  • 是的,并不是所有的爱好都不为空。一些记录可能没有、一个、两个或三个爱好。所以,您同意hobby# 列是重复组的事实,对吧?我知道解决方案,讨论的是他们是否重复组。但是,您的解决方案将使任何想要标准化 1NF 的人更清楚。 :)
【解决方案4】:

如果不知道存在哪些键以及表应该满足哪些依赖关系,就不可能确定它满足什么范式。我们所能做的就是根据您的属性名称进行猜测。

桌子有钥匙吗?例如,假设 Name 是候选键。如果每个元组的每个其他属性都允许有一个值(这意味着任何属性都不能为空),那么该表至少是第一范式。

【讨论】:

  • 好吧,假设键是一个名为idAUTO_INCREMENT 列类型。我们正在讨论hobby# 列,即它们是否是重复组。考虑到表已经有主键这一事实。
  • 如果表至少有一个键并且每个属性位置只包含一个值并且不允许空值,那么它在1NF中。
  • 这个确实允许NULLs,因此它不在1NF中?顺便说一句,您必须编辑您的答案,因为它的方式可能被视为评论。 :)
【解决方案5】:

如果表中的任何列接受空值,则表违反第一范式。假设没有空值,@dportas 已经提供了正确答案。

【讨论】:

  • original question 上的编辑显示了一个包含空值的表格。因此,根据您的回答,它违反了 1NF。因此,hobby# 的那些列是重复组。
  • @Shef:你的逻辑有缺陷。必须满足 1NF 的所有规则才能使设计处于 1NF 中。违反单个规则(无空值)并不意味着违反了所有规则。
【解决方案6】:

您的三爱好表设计可能违反了我通常所说的原始 1NF 的精神可能由于 dportas 和其他人给出的原因)。

然而事实证明,要找到[一组]正式且精确的“可衡量”标准来准确表达原始“精神”是极其困难的。这就是你的其他人在谈论“重复组的模糊性”时试图解释的原因。

在这里强调“正式”、“精确”和“可衡量”。存在满足“形式”、“精确”和“可测量”(即客观可观察)的所有其他范式的定义。对于 1NF,这很难(/不可能???)。如果你想知道为什么,试试这个:

您说问题是“这三个爱好栏是否构成重复组”。用“是”回答这个问题,然后为您的回答提供严格的正式基础。

您不能只说“列名相同,但编号后缀除外”。使违反此类规则的行为客观可观察/可衡量需要列举所有可能的后缀方式。

您不能只说“游泳,网球”同样可以是“网球,游泳”,因为要确定这一点需要检查表的外部谓词。如果这只是 "人 有爱好 并且也有 " ,那么两者确实是同样有效的(除了:并且由于封闭世界的假设,它实际上需要所有可能的爱好排列出现在表中!!!)。但是,如果该外部谓词是“人 上花费的时间最多,而在 上花费的时间最少”,那么“游泳,网球”NOT 也可以是“网球,游泳”。但是你如何对表目标的外部谓词做出这样的解释(对于所有可能的谓词)???

等等。等等

【讨论】:

  • +1。你在那里有很好的观点。这是列名的最不糟糕的选择。但是,你的论点确实成立,也许另一个人试图说服我是对的。
  • +1 指出仅查看数据库结构不能证明违反 1NF。
【解决方案7】:

该表违反第一范式。

第一范式对同一类型的多个列没有任何禁止。只要它们具有不同的列名,就可以了。

禁止“重复组”涉及嵌套记录——这种结构在分层数据库中很常见,但在关系数据库中通常是不可能的。

使用重复组的表格如下所示:

+-------+--------+  
| name  |hobbies |  
+-------+--------+
| kris  |+-----+ |  
|       ||ball | |
|       |+-----+ |
|       ||swim | |
|       |+-----+ |
|       ||dance| |
|       |+-----+ |
+-------+--------+
| james |+-----+ |  
|       ||eat  | |
|       |+-----+ |
|       ||sing | |
|       |+-----+ |
|       ||sleep| |
|       |+-----+ |
+-------+--------+
| amy   |+-----+ |  
|       ||swim | |
|       |+-----+ |
|       ||eat  | |
|       |+-----+ |
|       ||watch| |
|       |+-----+ |
+-------+--------+

在符合 1NF 的表中,所有值都可以通过表名、主键和列名来定位。但这对于需要进一步导航的重复组是不可能的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-19
    • 1970-01-01
    • 2018-11-13
    • 2012-09-22
    • 2015-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多