【问题标题】:What exactly does database normalization do?数据库规范化究竟是做什么的?
【发布时间】:2015-08-08 09:57:48
【问题描述】:

数据库新手,所以不会对简单的问题感到不安。 就我的谷歌搜索和收集的知识规范化而言,减少了数据冗余并提高了性能。但实际上,我不明白将主表划分为其他小表、应用它们之间的关系、使用所有可能的联合、子查询、连接等检索数据的确切原因,为什么我们不能拥有所有数据一个表并根据需要检索它们。我有点困惑。

【问题讨论】:

标签: database database-normalization


【解决方案1】:

主要原因是为了消除数据的重复,例如,如果您有一个具有多个地址的用户,并且您将此信息存储在一个表中,则用户信息将与每个地址条目一起重复。规范化会将地址分离到它们自己的表中,然后使用键将两者链接起来。这样您就不需要复制用户数据,并且您的数据库结构变得更加简洁。

完全规范化通常不会提高性能,事实上它通常会使性能变得更糟,但它会让您的数据不重复。事实上,在一些特殊情况下,我已经对一些特定数据进行了非规范化以提高性能。

【讨论】:

  • 所以如果没有重复你不应该规范化?
  • 如果您只有一个只有一个地址的用户列表,则无需将数据分解为多个表。我仍然建议为该数据使用唯一键。
  • 规范化涉及“消除数据的重复”,但日常用语含糊不清,而规范化实际上定义一个具体的事情,可以合理地称之为。 (即通过一个较短的行启用更新需要多个较长的行。)(即它“消除了更新异常”。)您的示例不需要需要规范化,您也不需要规范化它。此外,它也不是必然是坏的“重复”。规范化也不会像您的示例那样引入新列,即键。例如,您引入的 id 值“重复”,它们完全按照地址替换地址。
  • 规范化分解为多个连接到原始表的较小表。 (并且它不会添加新列。)性能变化取决于使用情况。例如,在较小的表基数的乘积与其总和的比率方面,它可以极大地提高性能。当我们需要原创时,人们总是关注加盟成本;但每次我们只使用一些我们节省的较小的。事实上,每当我们从多个表开始时,与使用更少的表相比,我们都直观地进行了规范化。 (即删除了一个JD)。
【解决方案2】:

归一化来自“正常”的数学概念。另一个词是“垂直的”。想象一个常规的两轴坐标系。向上移动只是改变 y 坐标,向侧面移动只是改变 x 坐标。所以每一个动作都可以分解为横向和上下运动。这两者是相互独立的。

数据库中的规范化本质上意味着同样的事情:如果您更改一条数据,这应该只更改数据库中的一条信息。想象一个电子邮件数据库:如果您将 ID 和收件人姓名存储在 Mails 表中,但 Users 表也将姓名与 ID 相关联,这意味着如果您更改用户名,您不仅必须在用户表中更改它,而且还要在该用户涉及的每条消息中进行更改。因此,轴“消息”和轴“用户”不是“垂直”或“正常”。

另一方面,如果 Mails 表只有用户 ID,对用户名的任何更改都将自动应用到所有消息,因为在检索消息时,所有用户信息都从 Users 表中收集(通过连接方式)。

【讨论】:

    【解决方案3】:

    最简单的数据库规范化是一种最小化数据冗余的方法。为此,存在某些形式的规范化。

    第一范式可以概括为:

    • 单个表中没有重复组。
    • 单独的表格以获取相关信息。
    • 表中与主键相关的所有项目。

    第二范式增加了另一个限制,基本上不是候选键一部分的每一列都必须依赖于每个候选键(候选键被定义为不能重复的最小列集表中)。

    第三范式更进一步,不是候选键的一部分的每一列都不能依赖于任何其他非候选键列。换句话说,它可以依赖于在候选键上。这导致了这样一种说法,即 3NF 依赖于密钥、整个密钥并且除了密钥之外什么都没有,所以请帮帮我 Codd1

    请注意,上述解释是针对您的问题而不是数据库理论家量身定制的,因此描述必然是简化的(我使用了“总结为”和“基本上”等短语)。

    数据库理论领域是一个复杂的领域,如果你真的想了解它,你最终必须了解它背后的科学。但是,就您的问题而言,希望这已经足够了。

    规范化是一种有价值的工具,可确保我们没有冗余数据(如果两个冗余区域不同步,这将成为一个真正的问题)。它通常不会提高性能。

    事实上,虽然所有数据库都应该从 3NF 开始,但有时为了提高性能,降低到 2NF 是可以接受的,前提是您了解并缓解潜在问题。

    请注意,还有“更高”级别的正常化,例如(显然)第四、第五和第六,还有 Boyce-Codd 和其他一些我不记得了。在绝大多数情况下,3NF 应该绰绰有余。


    1 如果您不知道 Edgar Codd(或 Christopher Date,就此而言)是谁,您可能应该研究他们,他们是父亲关系数据库理论。

    【讨论】:

    • @philipxy,不确定我是否理解你的第一点,我可以很容易地添加一个与键无关的列(例如,一个完全随机的数字)——这肯定会违反 1nf,是的?至于第二点,尽管“关键”一词可能会误导这个方向,但我在答案中的任何地方都看不到“主要”。如果您对如何避免这种情况有任何想法,请告诉我,否则我会在使用真正的计算机时试一试。
    • Re 1:不,它没有。规范化不是关于一些模糊的日常术语,例如“无关”。 is 相关的具有特定定义的特定术语是“功能上取决于”。)(我猜“键”是指 CK(候选键)。CK 的 定义是一个列集,其子行是唯一的,并且不包含其子行唯一的较小列集。关于“每列取决于每个键”,请参阅我的 cmets 其他答案。
    • Re 2:是的,理解“关键”的唯一方法是“PK”。 (这使你的子弹错了。)关于“如何避免这种情况”:它将涉及适当地使用“一些CK(s)”和/或“所有CK”。但是,如果您想用自己的话为2NF3NF 写一个正确 答案,那么您只需要使用语言和/或数学来清楚地表达相同的内容。我能说什么?好的写作需要努力撰写和反复改写,关注读者的观点。
    • @philipxy,好吧,我试着让它有点更正式,但我不想冒险让它变得如此枯燥没有人会阅读或理解它,更喜欢(如您所说)“关注读者的观点”。如果他们想要真正的肉,他们可能会去购买 Codd/Date 书籍,或者他们可以购买我的,自 Uni 以来我就没有真正使用过 :-) 感谢您的想法/帮助,by方式。
    • @philipxy,好的,添加了“免责声明”,即答案必须简化,针对 OP 的级别。希望这将满足两个阵营。
    【解决方案4】:

    我们使用规范化来减少由于数据插入、删除、更新而可能出现的异常情况。规范化不一定会提高性能。

    互联网上有很多资料,所以我不再在这里重复这些内容。但是你可以看看 Normalization rules Anomalies (还有其他人)

    【讨论】:

      【解决方案5】:

      除了以上所有,它只是有一定的意义。假设您有一个用户,并且您想记录他们拥有什么样的汽车。

      将所有内容放在一个表中,然后就可以了,直到某人拥有两辆汽车...然后,您将需要该人的两行,以及确保可以链接这两行的方法一起...

      如果你还想记录他们有多少只狗呢?同一张桌子有很多令人困惑的重复?另一个具有您自己的自定义逻辑来管理唯一用户的表?

      规范化让你远离很多这些问题...

      【讨论】:

      • 每个地址都有一行本身并没有错。只有当它存在时当某些其他事情是时,规范化才是恰当的......例如,当我们有多个地址多条狗并且时不是每户一只狗或每只狗每户。所以这真的不能解释异常。 (在 SteveTemple 的回答中查看我的 cmets。)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-17
      • 1970-01-01
      • 1970-01-01
      • 2013-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多