SQL 中的规范化:1NF、2NF、3NF 和 BCNF

已发表: 2021-03-12

规范化是确保关系数据库模型高效、适用于通用查询并且没有诸如插入、更新和删除异常等不良特征的系统过程,从而导致数据的完整性丢失。 此规范化过程还有助于消除数据冗余并减少任何插入、更新或删除操作后出现不一致的机会。

为了更好地理解,请考虑以下模式:学生(姓名、地址、学科、年级)

此模式存在一些问题或效率低下。

1)冗余:学生的地址在他注册的每个科目中重复。

2)更新异常:我们可能在一个元组(行)中更新了地址,而在其他行中保持不变。 因此,我们不会为每个学生提供始终如一的唯一地址。

3)插入异常:我们不会在没有注册至少一门学科的情况下记录学生的地址。 同样,当学生想要注册新学科时,可能会插入不同的地址。

4)删除异常:如果学生决定停止所有已注册的科目,那么学生的地址也会在删除过程中丢失。

因此,重要的是通过在元组添加、删除或更新操作之后不会创建异常的关系来表示用户数据。 这只能通过仔细分析完整性约束,尤其是数据库的数据依赖关系来实现。

应该设计关系,以便只有那些自然存在在一起的属性才被分组。 这主要可以通过对所有数据属性的含义的基本理解来完成。 但是,我们仍然需要一些正式的措施来确保我们的设计目标。

规范化是正式的措施。 它回答了为什么一个特定的属性组会比其他属性更好的问题。

截至今天存在七种范式:

  • 第一范式 (1NF)
  • 第二范式 (2NF)
  • 第三范式 (3NF)
  • Boyce-Codd 范式 (BCNF)
  • 第四范式 (4NF)
  • 第五范式 (5NF)
  • 第六或域键范式 (6NF)

阅读: SQL 中的视图类型

目录

第一范式(1NF 或最小形式)

  • 行没有从上到下的排序,列没有从左到右的排序。
  • 没有重复的行。
  • 每个行列交集都包含来自适用域的一个值或空值。 此条件指示所有列值都应该是原子的、标量的或仅包含单个值。 此处不允许在多列中重复信息或值。
  • 所有列都是规则的(即行没有隐藏组件,例如行 ID、对象 ID 或隐藏时间戳)。

让我们以未规范化的模式为例。 假设设计师希望记录客户的姓名和电话号码。 他们定义了一个客户表,如下所示:

客户编号名字_ 电话号码
123 比马尔萨哈555-861-2025
456 卡皮尔卡纳555-403-1659、555-776-4100
789 卡比塔罗伊555-808-9633

在这里,它不在 1 NF 中。 电话号码列不是原子的或没有标量值,即它有多个值,这在 1 NF 中是不允许的。

使其成为 1 NF

  • 我们将首先将我们的单个表分解(分解)为两个。
  • 每个表应该只包含一个实体的信息。
客户编号名字_
123 比马尔萨哈
456 卡皮尔卡纳
789 卡比塔罗伊

客户编号电话号码
123 555-861-2025
456 555-403-1659
456 555-776-4100
789 555-808-9633

此设计中不会出现重复的电话号码组。 相反,每个客户到电话号码的链接都出现在其自己的记录中。

结帐:最常见的 SQL 面试问题和答案

第二范式

每个范式都比其前身具有更多的约束条件。 因此,根据定义,任何处于第二范式 (2NF) 或更高形式的表也属于 1NF。 另一方面,在 1NF 中的表可能在也可能不在 2NF 中; 如果它在 2NF 中,它可能在也可能不在 3NF 中,依此类推。

当且仅当一个 1NF 表的非主属性在功能上都不依赖于候选键的一部分(正确子集)时,才称 1NF 表在 2NF 中。 (非主属性不属于任何候选键。)

请注意,当 1NF 表没有复合候选键(候选键由多个属性组成)时,该表自动处于 2NF。

检查是否将 FD 设置为 { BC 的关系 R (A, B, C, D, E) D,交流? 是,乙? E } 在 2NF 中?

  • 正如我们所看到的,通过应用隶属度算法,AC 的闭包是 (AC)+ = {A, C, B, E, D}。 但是它的子集都不能自己确定关系的所有属性,所以AC是这个关系的候选键。 此外,A 和 C 都不能从关系的任何其他属性派生,因此只有 1 个候选键,即 {AC}。
  • 这里 {A, C} 是主要属性,{B, D, E} 是非主要属性。
  • 关系 R 已经处于第一范式,因为 1NF 中的关系 DBMS 不允许多值或复合属性。

卑诗省? D 是第二范式,因为 BC 不是候选密钥 AC 的真子集,

交流电? BE 是第二范式,因为 AC 本身就是候选键,并且

乙? E 是第二范式 B 不是候选密钥 AC 的真子集。

因此,给定的关系 R 是第二范式。

第三范式

当且仅当对于它的每个功能依赖关系时,才称表处于 3NF 中。

X → A ,至少满足下列条件之一:

  • X 包含 A(即 X → A 是一个平凡的函数依赖),或者
  • X 是超级键,或
  • A 是主要属性(即,A 存在于候选键中)

3NF 的另一个定义表明,R 的每个非键属性都非传递地依赖(即直接依赖)R 的主键。这意味着没有非主属性(不是候选键的一部分)在功能上依赖于其他非主属性。 如果有两个依赖项,例如 A ? B 和 BC,那么从这些 FD 中,我们可以推导出 A ? C. 这种依赖AC 是传递的。

3NF 示例:

考虑以下关系 Order (Order#, Part, Supplier, UnitPrice, QtyOrdered) 与给定的 FD 集:

命令# ? 零件、供应商、订购数量和供应商、零件? 单价)

这里 Order# 是关系的关键。

使用 Amstrong 公理,我们得到

命令# ? 零件,订单? 供应商和订单? 订购数量。

命令# ? 部分,供应商和供应商,部分? 单价,都给出订单#? 单价。

因此,我们看到所有非主属性都依赖于键 (Order#)。 但是,Order# 和 UnitPrice 之间存在传递依赖关系。 所以这个关系不在 3NF 中。 我们如何在 3NF 中实现它?

我们不能存储任何供应商提供的任何零件的单价,除非有人为该零件下订单。 所以我们必须分解表格,使其遵循 3NF,如下所示。

订单(Order#、Part、Supplier、QtyOrdered)和价格主数据(Part、Supplier、UnitPrice)。

现在不存在传递依赖。 该关系在 3NF 中。

另请阅读:用于数据科学的 SQL

从世界顶级大学在线学习软件课程获得行政 PG 课程、高级证书课程或硕士课程,以加快您的职业生涯。

结论

规范化还有更多内容,例如 BCNF、4NF、5NF 和 6NF。 简而言之,BCNF 只不过是 3NF 的扩展,因为 3NF 的最后一条规则在这里不适用。 所有功能依赖项都需要在左侧具有关键属性,而在右侧没有。 (BCNF 也称为 3.5NF)。 然而,4NF 及以后的范式很少在常规实践中实施。

如果您有兴趣了解有关全栈开发的更多信息,请查看 upGrad & IIIT-B 的全栈软件开发执行 PG 计划,该计划专为工作专业人士设计,提供 500 多个小时的严格培训、9 个以上的项目、和任务、IIIT-B 校友身份、实用的实践顶点项目和顶级公司的工作协助。

什么是数据库规范化?

有哪些不同类型的范式?

范式是由关系数据库之父 Edgar F. Codd 开发的。 每个范式都是关系模型整体逻辑正确性的一个级别,并在数据库的实际设计中起到一定的作用。 第一个范式 1NF 是关于表设计的,它涉及删除重复项并确保每条数据在表中只表示一次。 第二种范式是关于可重复的列 - 将它们分解为多个表。 第三种范式是关于重复组 - 将它们分解为多个表。 第四种范式大约是 1NF、2NF 和 3NF - 确保表没有任何逻辑或反规范化。

如何规范化数据库?

规范化数据库是将其分解为最少数量的表的过程。 最后,数据库将没有重复的字段,也没有包含部分信息的行。 目的是确保所有数据都链接到所有其他相关数据,并且当一个记录发生更改时,可能与之相关的所有其他记录也会更改。