SQL 中的规范化

2024 年 8 月 29 日 | 阅读 6 分钟

本文将详细解释一个重要的 SQL 概念——范式化。

范式化是一种数据库设计技术,旨在消除不良特征,包括插入、更新和删除异常,并减少数据冗余和重复。范式化过程将较大的表分解为较小的表,并通过关系将这些较小的表连接起来。SQL 中范式化的目标是消除冗余(重复)数据,并确保数据正确存储。

一套称为范式化形式的准则构成了范式化过程的基础。借助这些规则,可以减少或消除将数据存储在单个表中时可能发生的异常、不一致和数据重复。

关系模型的发明者埃德加·科德提出了数据范式化的概念,从第一范式开始,并继续通过第二范式和第三范式对其进行了改进。后来,他与雷蒙德·F·博伊斯合作,建立了博伊斯-科德范式理论。

不同类型的范式化形式

范式化有不同的阶段,每个阶段都有其自身的需求和标准,下面将对其进行介绍和解释

  1. 1NF(第一范式)
  2. 2NF(第二范式)
  3. 3NF(第三范式)
  4. 4NF(第四范式)
  5. 5NF(第五范式)

1. 1NF

如果表遵循以下两个标准/规则,则称关系数据处于第一范式。

  • 每个表单元格中应只包含单个值(原子性)。
  • 每条记录都应是独特且唯一的。

请看下面的例子来理解第一范式。

例如: 让我们考虑下面的学生表来理解 1NF 概念。

Roll_no名称已选课程
11Ram英语,生物
12塞缪尔数学,物理
13Rehman化学

正如我们在前两条记录中观察到的,"已选课程"列在特定表单元格中包含多个值。这与 1NF 的规则相悖。为了纠正这个问题,我们需要将此表拆分,并且两个部分都应包含一个共同的列/属性。这个列就是超键。为了更简单地理解什么是超键,超键是一个用于唯一标识所有记录的属性。

所以,表格被分为如下部分

学生表

Roll_no名称
11Ram
12塞缪尔
13Rehman

课程表

Roll_no课程
11英文
11生物学
12数学
12物理
13化学

表中的所有记录都是原子的(每个表单元格都包含单个值),并且所有记录都是唯一的。因此,上述关系数据被称为处于 1NF。

2. 2NF

如果表遵循以下两个标准/规则,则称关系数据处于第二范式。

  • 数据应处于 1NF。
  • 表中每个非键列都应依赖于完整的主键,而不仅仅是其一部分。

例如: 请看下面名为“销售”的表,其中包含以下数据

订单编号客户编号客户姓名Product_id数量Product_name
101121James323笔记本电脑
102122罗德斯331平板电脑
103123威廉姆斯342衬衫
104124Smith351手表

正如我们在表中观察到的,主键不是单个属性,而是客户 ID 和订单 ID 这两个属性的组合。在这里,客户姓名属性只依赖于客户 ID 列,而不依赖于订单 ID 列。这与 2NF 规则相悖。

因此,为了纠正这个问题,销售表需要分为两个独立的表,一个用于订单,另一个用于客户。

订单表

订单编号客户编号Product_id数量
101121323
102122331
103123342
104124351

客户表

客户编号客户姓名
121James
122罗德斯
123威廉姆斯
124Smith

3. 3NF

如果表遵循以下两个标准/规则,则称关系数据处于第三范式。

  • 数据应处于 2NF
  • 所有非键列都必须仅依赖于主键,而不依赖于任何其他非键列。

例如: 请看下面的例子,以便清楚地理解第三范式的概念。

员工编号namedepartment部门编号经理编号经理姓名salary
501James营销121101简·霍珀20000
502约翰逊测试122102威廉·史密斯50000
503大卫研发部123103迈克尔·多伊75000

这里的Primary Key是employee_id属性。部门、经理姓名和薪水列不仅依赖于Employee ID,还依赖于Manager ID属性。这与3NF规则相悖。

为了纠正这个问题并将其结构化为第三范式,我们需要将整个表分成三个部分,其中一部分用于员工,第二部分用于部门,最后一部分用于经理。

Employees 表

员工编号名称部门编号经理编号薪金
501James12110120000
502约翰逊12210250000
503大卫12310375000

部门表

部门编号部门名称
121营销
122测试
123研发部

经理表

经理编号经理姓名
101简·霍珀
102威廉·史密斯
103迈克尔·多伊

现在,“经理姓名”列仅依赖于“经理 ID”列,而“部门”和“薪水”列分别仅依赖于“部门 ID”和“员工 ID”。这符合 3NF 的标准。

第四范式

如果表遵循以下两个标准/规则,则称关系数据处于第四范式。

  • 数据应已处于 3NF
  • 关系数据不应包含任何非平凡的多值依赖。

首先我们需要了解什么是多值依赖。

当一个属性或属性组合对于另一个属性或属性组合的单个值可以有多个值时,这种情况称为多值依赖(MVD)。

例如: 请看下面的例子,以便清楚地理解第四范式的概念。考虑下面的“订单”表,它由以下数据组成

订单编号客户编号客户姓名Product_idProduct_name产品描述
101121James32笔记本电脑游戏笔记本电脑
101121James33小说
103122罗德斯33小说
104124Smith35手表智能手表
104124Smith36Shirt正装衬衫

在此表中,我们可以清楚地观察到存在多值依赖,因为对于订单 ID 和产品 ID 的每个组合,产品名称和产品描述都有多个值。例如,订单 ID 101 和产品 ID 32 的产品名称为“笔记本电脑”,产品描述为“游戏笔记本电脑”,而订单 ID 101 和产品 ID 33 的产品名称为“图书”,产品描述为“小说”。

因此,为了消除这种多值依赖并将上述数据结构化为第四范式,我们必须将整个表拆分为单独的部分,一个用于订单,另一个用于产品。结果如下:

订单表

订单编号客户编号客户姓名
101121James
103122罗德斯
104124Smith

产品表

订单编号Product_idProduct_name产品描述
10132笔记本电脑游戏笔记本电脑
10133小说
10333小说
10435手表智能手表
10436Shirt正装衬衫

现在,结果表以第四范式显示,没有任何多值依赖。

第五范式

当表的所有非平凡依赖都基于主键时,该表被认为是 5NF 规范化的。因此,数据库中没有冗余,并且由重复更新引起的任何潜在数据异常也被消除。

示例

请看下面的表格,以说明 5NF。

图书编号标题作者编号作者姓名作者邮箱
11Python 入门101K. 基肖尔[email protected]
11Python 入门102L. 拉维[email protected]
12软件测试103P. 戈皮[email protected]
12软件测试104R. 约瑟夫[email protected]

关系数据是冗余/重复的,即同一本书名被分配给两位作者。由于这种冗余,更新一位作者的电子邮件可能需要更新表中该作者的所有其他实例。

我们必须在表中找到多值依赖才能应用 5NF。在这种情况下,“图书 ID”和“作者 ID”属性之间存在多值依赖,因为一本书和一个作者都可能拥有多个作者。

基于多值依赖,我们可以将“图书”表拆分为“图书”表和“作者”表。新表将包含以下属性

图书表

图书编号标题
11Python 入门
12软件测试

作者表

作者编号作者姓名作者邮箱
101K. 基肖尔[email protected]
102L. 拉维[email protected]
103P. 戈皮[email protected]
104R. 约瑟夫[email protected]

现在,通过将原始表分解为两个新表,消除了原始表中的冗余。这种分解满足了第五范式的要求。因此,上述关系数据已结构化为第五范式。


下一主题SQL 聚合函数