110

为什么数据库人员继续进行规范化?

它是什么?它有什么帮助?

它适用于数据库之外的任何东西吗?

4

8 回答 8

185

规范化基本上是设计一个数据库模式,以避免重复和冗余数据。如果相同的信息在数据库中的多个位置重复出现,则可能会在一个位置更新而不在另一个位置更新,从而导致数据损坏。

从 1. 范式到 5. 范式有多个规范化级别。每个范式都描述了如何摆脱一些特定的问题。

第一范式 (1NF) 是特殊的,因为它与冗余无关。1NF 不允许嵌套表,更具体地说是允许表作为值的列。SQL首先不支持嵌套表,因此大多数普通关系数据库默认情况下都是1NF。所以我们可以在剩下的讨论中忽略 1NF。

范式 2NF 到 5NF 都涉及在同一个表中多次表示相同信息的情况。

例如,考虑一个卫星和行星数据库:

Moon(PK) | Planet  | Planet kind
------------------------------
Phobos   | Mars    | Rock
Daimos   | Mars    | Rock
Io       | Jupiter | Gas
Europa   | Jupiter | Gas
Ganymede | Jupiter | Gas

冗余是显而易见的:木星是一颗气体行星的事实被重复了三遍,每个月亮一个。这是对空间的浪费,但更严重的是,这种模式会使不一致的信息成为可能:

Moon(PK) | Planet  | Planet kind
------------------------------
Phobos   | Mars    | Rock
Deimos   | Mars    | Rock
Io       | Jupiter | Gas
Europa   | Jupiter | Rock <-- Oh no!
Ganymede | Jupiter | Gas

查询现在可以给出不一致的结果,这可能会产生灾难性的后果。

(当然,数据库不能防止输入错误的信息。但它可以防止不一致的信息,这同样是一个严重的问题。)

标准化设计会将表格拆分为两个表格:

Moon(PK) | Planet(FK)     Planet(PK) | Planet kind
---------------------     ------------------------
Phobos   | Mars           Mars       | Rock
Deimos   | Mars           Jupiter    | Gas
Io       | Jupiter 
Europa   | Jupiter 
Ganymede | Jupiter 

现在没有事实被重复多次,因此不存在数据不一致的可能性。(看起来仍然存在一些重复,因为行星名称是重复的,但是将主键值作为外键重复不会违反规范化,因为它不会引入数据不一致的风险。)

经验法则 如果相同的信息可以用更少的单个单元格值表示,不计算外键,那么应该通过将表拆分为更多表来规范化表。例如,第一个表有 12 个单独的值,而两个表只有 9 个单独的(非 FK)值。这意味着我们消除了 3 个冗余值。

我们知道相同的信息仍然存在,因为我们可以编写一个join返回与原始未规范化表相同的数据的查询。

如何避免此类问题? 通过对概念模型进行一些考虑,例如通过绘制实体关系图,可以轻松避免规范化问题。行星和卫星具有一对多的关系,这意味着它们应该在两个具有外键关联的不同表中表示。当具有一对多或多对多关系的多个实体在同一表行中表示时,就会出现规范化问题。

标准化重要吗?是的,这非常重要。通过使数据库具有规范化错误,您将面临将无效或损坏的数据放入数据库的风险。由于数据“永远存在”,因此很难在首次进入数据库时​​摆脱损坏的数据。

但我并不认为区分从 2NF 到 5NF 的不同范式很重要。当模式包含冗余时通常非常明显 - 只要问题得到解决,违反的 3NF 还是 5NF 都不那么重要。

(还有一些额外的正常形式,如 DKNF 和 6NF,它们仅与数据仓库等特殊用途系统相关。)

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

关于标准化有许多误解:

  • 有些人认为规范化的数据库速度较慢,而非规范化提高了性能。然而,这仅在非常特殊的情况下才是正确的。通常,规范化数据库也是最快的。

  • 有时标准化被描述为一个渐进的设计过程,您必须决定“何时停止”。但实际上标准化水平只是描述了不同的具体问题。由高于 3rd NF 的范式解决的问题首先是非常罕见的问题,因此您的模式很可能已经在 5NF 中。

它适用于数据库之外的任何东西吗?不直接,不。规范化的原则对于关系数据库来说是非常具体的。然而,一般的基本主题——如果不同的实例可能不同步,你不应该有重复的数据——可以广泛应用。这基本上就是DRY 原则

于 2008-10-29T13:14:59.937 回答
19

最重要的是,它用于从数据库记录中删除重复项。例如,如果您有不止一个地方(表格)可以出现一个人的名字,您可以将该名字移动到一个单独的表格中并在其他任何地方引用它。这样,如果您以后需要更改人名,您只需在一个地方进行更改。

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

我的建议是从良好程度的规范化开始,仅在真正需要时才进行去规范化

PS 也检查这篇文章:http ://en.wikipedia.org/wiki/Database_normalization阅读更多关于这个主题和所谓的范式

于 2008-10-29T13:07:52.777 回答
7

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

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

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

于 2008-10-29T13:13:54.200 回答
5

它旨在减少数据的冗余。

有关更正式的讨论,请参阅 Wikipedia 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 后,下一步通常是以逻辑方式对其进行反规范化,以加快查询速度并降低某些常见插入的复杂性。但是,如果不先对其进行适当的规范化,您将无法做到这一点。

这个想法是将冗余信息减少到单个条目。这在地址等字段中特别有用,其中 Chris 先生将他的地址提交为 Unit-7 123 Main St.,而 Chris 女士列出了 Suite-7 123 Main Street,这将在原始表格中显示为两个不同的地址。

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

于 2008-10-29T13:14:03.700 回答
4

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

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

偏离第一范式将导致访问异常,这意味着您必须分解和扫描各个值才能找到您要查找的内容。例如,如果其中一个值是先前响应中给出的字符串“Ford, Cadillac”,并且您正在查找“Ford”的所有出现,您将不得不打开字符串并查看子串。这在某种程度上违背了将数据存储在关系数据库中的目的。

自 1970 年以来,第一范式的定义发生了变化,但这些差异现在不必担心。如果您使用关系数据模型设计 SQL 表,您的表将自动处于 1NF 中。

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

这些是逻辑问题,而不是性能问题或空间问题。有时您可以通过仔细编程来绕过这些更新异常。有时(通常)最好通过遵守正常形式来防止出现问题。

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

您可能真正想要应用规范化中教授的概念的地方是,当您获得遗留数据、遗留数据库或由记录组成的文件时,并且数据的设计完全无视规范形式和离开的后果从他们。在这些情况下,您可能需要发现与规范化的偏差,并更正设计。

警告:正常化通常带有宗教色彩,好像每次偏离完全正常化都是一种罪过,是对 Codd 的冒犯。(那里有点双关语)。不要买那个。当您真正、真正地学习数据库设计时,您不仅会知道如何遵守规则,而且会知道何时可以安全地打破规则。

于 2008-10-31T13:25:25.747 回答
3

什么是标准化?

规范化是一个逐步的形式化过程,它允许我们以最小化数据冗余更新异常的方式分解数据库表。

标准化过程礼貌
在此处输入图像描述

第一范式当且仅当每个属性的域仅包含原子值(原子值是不能被划分的值),并且每个属性的值仅包含来自该域的单个值(例如:-性别栏是:“M”、“F”。)。

第一范式强制执行以下标准:

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

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

第三范式= 2NF + 无传递依赖,即所有非键属性完全功能依赖于主键。

Boyce–Codd 范式(或 BCNF 或 3.5NF)是第三范式(3NF)的稍强版本。

注意:- Second、Third 和 Boyce-Codd 范式关注函数依赖。 例子

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

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

于 2015-07-27T01:20:22.697 回答
2

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

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

乍一看,这真的很好,因为您遇到一些同步问题的机会接近于零,您总是知道您的数据在哪里,等等。但是,您的表数量可能会增加,并且您将遇到交叉数据的问题并得到一些总结性的结果。

因此,最后您将完成非纯规范化的数据库设计,并带有一些冗余(它将处于某些可能的规范化级别)。

于 2008-10-29T13:09:56.827 回答
2

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

有关关系模型的文献区分了几种不同的范式,但这些区别几乎没有实际意义。根据经验,如果您复制的值只能存储在一个地方,则架构不会被规范化。

于 2020-04-20T21:09:37.880 回答