什么是规范化(或规范化)?

时间:2008-10-29 13:01:41

标签: database-design normalization relational

为什么数据库人员继续关于规范化?

这是什么?它有什么用?

它是否适用于数据库之外的任何内容?

11 个答案:

答案 0 :(得分:164)

规范化基本上是设计数据库模式,以避免重复和冗余数据。如果某些数据在数据库中的多个位置重复,则存在在一个位置而不是另一个位置更新的风险,从而导致数据损坏。

从正常形式到正常形式有许多标准化水平。每个正常形式都描述了如何摆脱一些通常与冗余相关的特定问题。

一些典型的规范化错误:

(1)在单元格中有多个值。例如:

UserId | Car
---------------------
1      | Toyota
2      | Ford,Cadillac

这里“Car”列(它是一个字符串)有几个值。这冒犯了第一个正常形式,即每个单元格应该只有一个值。我们可以通过每辆车单独排一行来规范化这个问题:

UserId | Car
---------------------
1      | Toyota
2      | Ford
2      | Cadillac

在一个单元格中有多个值的问题是更新很棘手,查询很棘手,而且无法应用索引,约束等。

(2)具有冗余的非密钥数据(即,在多行中不必要地重复数据)。例如:

UserId | UserName | Car
-----------------------
1      | John     | Toyota
2      | Sue      | Ford
2      | Sue      | Cadillac

此设计是一个问题,因为每个列都会重复名称,即使名称始终由UserId确定。这使得理论上可以在一行而不是另一行中更改Sue的名称,这是数据损坏。通过将表拆分为两个并创建主键/外键关系来解决该问题:

UserId(FK) | Car               UserId(PK) | UserName
---------------------          -----------------
1          | Toyota            1          | John
2          | Ford              2          | Sue
2          | Cadillac

现在看起来我们仍然有冗余数据,因为UserId会被重复;但是,PK / FK约束确保不能单独更新值,因此完整性是安全的。

重要吗?是的,非常重要。通过使数据库具有规范化错误,您可以避免将无效或损坏的数据导入数据库。由于数据“永远存在”,因此在首次进入数据库时​​很难摆脱损坏的数据。

不要害怕正常化。标准化水平的官方技术定义非常钝。这听起来像归一化是一个复杂的数学过程。但是,规范化基本上只是常识,你会发现如果你使用常识设计数据库模式,它通常会被完全规范化。

关于规范化存在许多误解:

  • 有些人认为规范化数据库较慢,而非规范化可以提高性能。但这只适用于非常特殊的情况。通常,规范化数据库也是最快的。

  • 有时归一化被描述为一个渐进的设计过程,你必须决定“何时停止”。但实际上,标准化水平只描述了不同的具体问题。正常形式在第3 NF以上解决的问题首先是非常罕见的问题,所以很有可能你的架构已经在5NF。

它是否适用于数据库以外的任何内容?不是直接,不是。规范化的原则对于关系数据库非常具体。但是,一般的基本主题 - 如果不同的实例可能不同步,您不应该有重复的数据 - 可以广泛应用。这基本上是DRY principle

答案 1 :(得分:44)

normalisation的规则(来源:未知)

  • 键(1NF
  • 整个密钥(2NF
  • 除了密钥(3NF
  • 外什么都没有

...帮助我Codd.

答案 2 :(得分:19)

最重要的是,它可以消除数据库记录中的重复。 例如,如果您有多个地方(表格)可以显示某个人的姓名,您可以将该名称移至单独的表格并在其他地方引用该名称。这样,如果您以后需要更改人名,您只需在一个地方更改它。

对于正确的数据库设计至关重要,理论上您应尽可能使用它来保持数据的完整性。但是,当从许多表中检索信息时,您会丢失一些性能,这就是为什么有时您会看到在性能关键应用程序中使用的非规范化数据库表(也称为扁平化)。

我的建议是从良好的规范化开始,只在真正需要时进行去标准化

P.S。还请查看以下文章:http://en.wikipedia.org/wiki/Database_normalization,详细了解该主题以及所谓的普通表单

答案 3 :(得分:7)

规范化用于消除表中列之间的冗余和功能依赖性的过程。

存在几种常规形式,通常用数字表示。数字越大意味着冗余和依赖性越少。任何SQL表都是1NF(第一个普通形式,几乎是定义)规范化意味着以可逆的方式更改模式(通常是对表进行分区),给出一个功能相同的模型,除了冗余和依赖性较小。

数据的冗余和依赖性是不可取的,因为它可能在修改数据时导致不一致。

答案 4 :(得分:5)

旨在减少数据冗余。

有关更正式的讨论,请参阅维基百科http://en.wikipedia.org/wiki/Database_normalization

我会给出一个有点过分简单的例子。

假设组织的数据库通常包含家庭成员

id, name, address
214 Mr. Chris  123 Main St.
317 Mrs. Chris 123 Main St.

可以归一化为

id name familyID
214 Mr. Chris 27
317 Mrs. Chris 27

和家庭表

ID, address
27 123 Main St.

近完全标准化(BCNF)通常不用于生产,但是是一个中间步骤。一旦将数据库放入BCNF,下一步通常是以逻辑方式对其进行反规范化,以加快查询速度并降低某些常见插入的复杂性。但是,如果没有先正确地对它进行规范化,你就无法做到这一点。

这个想法是将冗余信息简化为单个条目。这在地址这样的领域特别有用,其中克里斯先生提交了他的地址,作为Unit-7 123 Main St.和Chris夫人列出Suite-7 123 Main Street,它将在原始表中显示为两个不同的地址。

通常,使用的技术是查找重复的元素,并将这些字段隔离到具有唯一ID的另一个表中,并使用引用新表的主键替换重复的元素。

答案 5 :(得分:3)

引用CJ日期:理论是实用的。

退出规范化将导致数据库出现某些异常现象。

离开First Normal Form会导致访问异常,这意味着您必须分解并扫描单个值才能找到您要查找的内容。例如,如果其中一个值是早期响应中给出的字符串“Ford,Cadillac”,并且您正在查找“Ford”的所有发生,那么您将不得不打开字符串并查看子。这在某种程度上违背了将数据存储在关系数据库中的目的。

自1970年以来,第一范式的定义发生了变化,但这些差异现在不需要关注。如果使用关系数据模型设计SQL表,则表将自动为1NF。

离开第二范式及更高版本会导致更新异常,因为同一事实存储在多个地方。这些问题使得在不存储可能不存在的其他事实的情况下存储某些事实是不可能的,因此必须发明。或者当事实发生变化时,您可能必须找到存储事实的所有plces并更新所有这些位置,以免最终出现与自身相矛盾的数据库。并且,当您从数据库中删除一行时,您可能会发现,如果这样做,您将删除存储仍然需要的事实的唯一位置。

这些是逻辑问题,而不是性能问题或空间问题。有时您可以通过仔细编程来解决这些更新异常。有时(通常)最好通过坚持正常形式来首先防止问题。

尽管已经说过的是有价值的,但应该提到的是,规范化是一种自下而上的方法,而不是自上而下的方法。如果您在分析数据和初始设计时遵循某些方法,则可以保证设计至少符合3NF。在许多情况下,设计将完全标准化。

您可能真正想要应用规范化中教授的概念,即您从遗留数据库或遗留数据库中获取遗留数据时,或者完全忽略了正常形式和数据离开他们的后果。在这些情况下,您可能需要发现规范化的偏差,并更正设计。

警告:正常化通常带有宗教色彩,好像每次背离完全正常化都是罪,是对Codd的冒犯。 (小双关语)不要买那个。当你真的,真正学习数据库设计时,你不仅知道如何遵守规则,而且知道什么时候可以安全地破解它们。

答案 6 :(得分:2)

规范化是基本概念之一。这意味着两件事互不影响。

在数据库中,具体意味着两个(或更多)表不包含相同的数据,即没有任何冗余。

第一眼看上去真的很好,因为你有一些同步问题的机会几乎为零,你总是知道你的数据在哪里,等等。但是,你的桌子数量可能会增长,你会遇到问题。交叉数据并获得一些汇总结果。

所以,最后你将完成数据库设计,这个数据库设计不是纯粹的规范化,有一些冗余(它将处于一些可能的规范化水平)。

答案 7 :(得分:1)

  

什么是规范化?

规范化是一个逐步形式化的正式流程,它允许我们以最小化数据冗余update anomalies的方式分解数据库表。

规范化过程
enter image description here Courtesy

第一范式当且仅当每个属性的域只包含原子值(原子值是不能分割的值)时,每个属性的值只包含一个值来自该域名(示例: - 性别列的域名为:" M"," F"。)。

第一个普通表单强制执行以下条件:

  • 消除各个表中的重复组。
  • 为每组相关数据创建单独的表。
  • 使用主键识别每组相关数据

第二范式 = 1NF +没有部分依赖关系,即所有非关键属性都完全依赖于主键。

第三范式 = 2NF +没有传递依赖关系,即所有非关键属性仅在主键上直接完全依赖。

Boyce-Codd普通形式(或BCNF或3.5NF)是第三范式(3NF)的略强版本。

注意: - 第二,第三和Boyce-Codd普通形式与功能依赖关系有关。 Examples

第四范式 = 3NF +删除多值依赖

第五范式 = 4NF +删除连接依赖

答案 8 :(得分:0)

正如Martin Kleppman在他的《设计数据密集型应用程序》中所说:

关系模型上的文献可以区分几种不同的范式,但是这种区分几乎没有实际意义。根据经验,如果要复制可能只存储在一个位置的值,则该架构不会标准化。

答案 9 :(得分:0)

什么是规范化?

规范化是将大型数据库表分为较小的表以减少数据冗余的过程。

什么是数据冗余?

数据冗余是数据库中不必要的数据重复,这不仅增加了数据库的大小,而且还会导致数据异常。

什么是数据异常?

异常是当数据冗余过多时发生的问题,这表明数据库的计划不充分且未规范化。数据异常有三种类型:

  1. 更新异常:当我们尝试更新表中的记录时会发生这种情况。在员工表中,我们为每个项目都有一个项目经理。现在,每个项目很可能有多于一名员工,这意味着我们表中有多条记录。对于每条记录,我们都在重复项目代码,项目名称和项目经理。现在,如果我们必须更换项目经理,那么说说从Gadir Shaikh到Hamza Imran的GLO项目。对于项目为GLO的每条记录,我们都必须对其进行更改。我们可能会错过一两个条目,使数据库处于不一致状态。在某些记录中,项目经理是Qadir Shaikh;在其他记录中,项目经理是Hamza Imran。
  2. 插入异常::假设我们要添加一个新雇员,该雇员最近被雇用并且目前正在接受培训,因此尚未分配任何项目。我们无法添加没有项目详细信息的员工,或者必须在项目字段中填充空值。或假设我们要在数据库中添加一个从客户那里收到的新项目,但我们尚未开始进行该项目,因此,目前没有任何员工分配给该项目。但是,由于employee_id(主键)已与员工链接,因此我们无法在没有任何员工的情况下存储项目详细信息。
  3. 删除异常::假设我们的项目NJAS已完成,我们希望将其从表中删除,因此我们将删除该项目为NJAS的表中的所有条目。但是,如果这样做,我们还将删除正在从事此项目的所有员工(Umer shaikh所有其他员工)的​​记录。我们可以通过标准化“员工”表来删除这些异常。有五个规则可对表格进行规范化。每个规则称为标准格式。还有另一种范式称为Boyce Codd范式,也称为3.5范式。让我们一一看一下。

普通表格的类型:

  • 第一个范式表示每个值都应具有多个值
  • 第二范式删除了部分依赖
  • 第三个范式删除了传递依存关系
  • Boyce Codd Normal Form(3NF的严格版本)
  • 第四个范式删除多值依赖项
  • 第5个范式删除联接依赖

有关更多详细信息,您可以阅读本文以了解所有常规形式以及如何应用它们

What is Normalization? | How to apply Normalization up to the 5th Normal Form?

答案 10 :(得分:-10)

它有助于防止重复(以及更糟糕的,冲突的)数据。

但可能对性能产生负面影响。