跳转到内容

数据库设计/规范化

来自维基教科书,开放世界中的开放书籍

规范化应该是数据库设计过程的一部分。然而,很难将规范化过程与 ER 建模过程分离,因此这两种技术应该同时使用。

使用实体关系图 (ERD) 来提供组织数据需求和操作的大图或宏观视图。这可以通过一个迭代过程创建,该过程涉及识别相关实体、它们的属性及其关系。

规范化过程侧重于特定实体的特征,并代表 ERD 中实体的微观视图。

什么是规范化?

[编辑 | 编辑源代码]

规范化是关系理论的一个分支,它提供了设计见解。它是确定表中存在多少冗余的过程。规范化的目标是

  • 能够描述关系模式的冗余程度
  • 提供用于转换模式以消除冗余的机制

规范化理论很大程度上借鉴了函数依赖理论。规范化理论定义了六种范式 (NF)。每种范式都涉及模式必须满足的一组依赖属性,并且每种范式都对更新异常的存在或不存在提供保证。这意味着更高的范式具有更少的冗余,因此更新问题更少。

数据库中的所有表都可以处于我们将要讨论的范式之一。理想情况下,我们只希望 PK 到 FK 的冗余最小。所有其他内容都应该从其他表中推导出来。有六种范式,但我们只关注前四种,它们是

  • 第一范式 (1NF)
  • 第二范式 (2NF)
  • 第三范式 (3NF)
  • Boyce-Codd 范式 (BCNF)

BCNF 很少使用。

第一范式 (1NF)

[编辑 | 编辑源代码]

第一范式中,在每行和每列的交点处只允许单个值;因此,没有重复组。

要规范化包含重复组的关系,请删除重复组并形成两个新的关系。

新关系的 PK 是原始关系的 PK 与新创建关系的属性的组合,用于唯一标识。

1NF 的过程

[编辑 | 编辑源代码]

我们将使用来自学校数据库的下面的 Student_Grade_Report 表作为我们的示例来解释 1NF 的过程。

Student_Grade_Report (StudentNo, StudentName, Major, CourseNo, CourseName, InstructorNo, InstructorName, InstructorLocation, Grade)

  • 在 Student Grade Report 表中,重复组是课程信息。一个学生可以修很多门课。
  • 删除重复组。在本例中,它是每个学生的课程信息。
  • 为新表识别 PK。
  • PK 必须唯一地识别属性值 (StudentNo 和 CourseNo)。
  • 删除与课程和学生相关的所有属性后,您将剩下学生课程表 (StudentCourse)。
  • 学生表 (Student) 现在处于第一范式,重复组已删除。
  • 下面显示了两个新表。

Student (StudentNo, StudentName, Major)

StudentCourse (StudentNo, CourseNo, CourseName, InstructorNo, InstructorName, InstructorLocation, Grade)

如何更新 1NF 异常

[编辑 | 编辑源代码]

StudentCourse (StudentNo, CourseNo, CourseName, InstructorNo, InstructorName, InstructorLocation, Grade)

  • 要添加新课程,我们需要一个学生。
  • 当需要更新课程信息时,我们可能会出现不一致。
  • 要删除一个学生,我们也可能会删除有关课程的关键信息。

第二范式 (2NF)

[编辑 | 编辑源代码]

对于第二范式,关系必须首先处于 1NF。当且仅当 PK 包含单个属性时,关系才会自动处于 2NF。

如果关系具有复合 PK,则每个非键属性必须完全依赖于整个 PK 而不是 PK 的子集(即,必须不存在部分依赖或增补)。

2NF 的过程

[编辑 | 编辑源代码]

要转到 2NF,表必须首先处于 1NF。

  • Student 表已经处于 2NF,因为它具有单列 PK。
  • 检查 Student Course 表时,我们看到并非所有属性都完全依赖于 PK;具体来说,所有课程信息。唯一完全依赖的属性是成绩。
  • 识别包含课程信息的新表。
  • 为新表识别 PK。
  • 下面显示了三个新表。

Student (StudentNo, StudentName, Major)

CourseGrade (StudentNo, CourseNo, Grade)

CourseInstructor (CourseNo, CourseName, InstructorNo, InstructorName, InstructorLocation)

如何更新 2NF 异常

[编辑 | 编辑源代码]
  • 添加新讲师时,我们需要一门课程。
  • 更新课程信息可能会导致讲师信息的不一致。
  • 删除课程也可能会删除讲师信息。

第三范式 (3NF)

[编辑 | 编辑源代码]

要处于第三范式,关系必须处于第二范式。此外,所有传递依赖必须被删除;非键属性不得函数依赖于另一个非键属性。

3NF 的过程

[编辑 | 编辑源代码]
  • 从每个具有传递关系的表中消除所有依赖于传递关系的属性。
  • 使用已删除的依赖项创建新的表。
  • 检查新表以及已修改的表以确保每个表都有一个决定因素,并且没有表包含不合适的依赖项。
  • 请参见下面的四个新表。

Student (StudentNo, StudentName, Major)

CourseGrade (StudentNo, CourseNo, Grade)

Course (CourseNo, CourseName, InstructorNo)

Instructor (InstructorNo, InstructorName, InstructorLocation)

在此阶段,第三范式中不应该有任何异常。让我们看一下此示例的依赖关系图(图 12.1)。第一步是删除重复组,如上所述。

Student (StudentNo, StudentName, Major)

StudentCourse (StudentNo, CourseNo, CourseName, InstructorNo, InstructorName, InstructorLocation, Grade)

为了回顾学校数据库的规范化过程,请查看图 12.1 中显示的依赖关系。

图 12.1 依赖关系图,由 A. Watt 提供。

图 12.1 中使用的缩略语如下

  • PD:部分依赖项
  • TD:传递依赖项
  • FD:完全依赖项(注意:FD 通常代表函数依赖项。在图 12.1 中使用 FD 作为完全依赖项的缩写只在图 12.1 中使用。)

Boyce-Codd 范式 (BCNF)

[编辑 | 编辑源代码]

当一个表有多个候选键时,即使关系处于 3NF,也可能导致异常。*Boyce-Codd 范式*是 3NF 的一种特殊情况。当且仅当每个决定因素都是候选键时,关系才处于 BCNF。

BCNF 示例 1

[编辑 | 编辑源代码]

考虑以下表 (St_Maj_Adv)。

学生 ID 专业 导师
111 物理 史密斯
111 音乐
320 数学 多布斯
671 物理 怀特
803 物理 史密斯

此表的*语义规则*(应用于数据库的业务规则)为

  1. 每个学生可以主修多个科目。
  2. 对于每个专业,给定学生只有一个导师。
  3. 每个专业有多个导师。
  4. 每个导师只指导一个专业。
  5. 每个导师指导一个专业中的多个学生。

此表的函数依赖关系列在下面。第一个是候选键;第二个不是。

  1. 学生 ID, 专业 ——>  导师
  2. 导师  ——>  专业

此表的异常包括

  1. 删除 - 学生删除导师信息
  2. 插入 - 新导师需要学生
  3. 更新 - 不一致

注意:没有单个属性是候选键。

PK 可以是学生 ID, 专业 或 学生 ID, 导师。

要将 St_Maj_Adv 关系简化为 BCNF,您需要创建两个新表

  1. St_Adv (学生 ID, 导师)
  2. Adv_Maj (导师, 专业)

St_Adv 表                                                                    

学生 ID 导师
111 史密斯
111
320 多布斯
671 怀特
803 史密斯

Adv_Maj 表

导师 专业
史密斯 物理
音乐
多布斯 数学
怀特 物理

BCNF 示例 2

[编辑 | 编辑源代码]

考虑以下表 (Client_Interview)。

客户编号 面试日期 面试时间 员工编号 房间编号
CR76 02 年 5 月 13 日 10.30 SG5 G101
CR56 02 年 5 月 13 日 12.00 SG5 G101
CR74 02 年 5 月 13 日 12.00 SG37 G102
CR56 02 年 7 月 1 日 10.30 SG5 G102

FD1 – 客户编号, 面试日期 –> 面试时间, 员工编号, 房间编号  (PK)

FD2 – 员工编号, 面试日期, 面试时间 –> 客户编号      (候选键:CK)

FD3 – 房间编号, 面试日期, 面试时间 –> 员工编号, 客户编号    (CK)

FD4 – 员工编号, 面试日期 –> 房间编号

当且仅当每个决定因素都是候选键时,关系才处于 BCNF。我们需要创建一个包含前三个 FD 的表 (Client_Interview2 表) 和另一个用于第四个 FD 的表 (StaffRoom 表)。

Client_Interview2 表

客户编号 面试日期 面试时间 员工编号
CR76 02 年 5 月 13 日 10.30 SG5
CR56 02 年 5 月 13 日 12.00 SG5
CR74 02 年 5 月 13 日 12.00 SG37
CR56 02 年 7 月 1 日 10.30 SG5

StaffRoom 表

员工编号 面试日期 房间编号
SG5 02 年 5 月 13 日 G101
SG37 02 年 5 月 13 日 G102
SG5 02 年 7 月 1 日 G102

规范化和数据库设计

[编辑 | 编辑源代码]

在数据库设计的规范化过程中,请确保在创建表结构之前,建议的实体满足所需的范式。如果许多现实世界的数据库在设计时不当,或者在一段时间内被错误地修改,就会出现异常。您可能会被要求重新设计和修改现有的数据库。如果表没有正确规范化,这可能是一项巨大的任务。

关键术语和缩略语

[编辑 | 编辑源代码]
Boyce-Codd 范式 (BCNF)
  第 3 NF 的一种特殊情况
第一范式 (1NF)
在每一行和每一列的交点处只允许单个值,因此没有重复组
规范化
确定表中存在多少冗余的过程
第二范式 (2NF)
关系必须处于 1NF,并且 PK 包含单个属性
语义规则
应用于数据库的业务规则
第三范式 (3NF)
关系必须处于 2NF,并且所有传递依赖关系必须被删除;非键属性不能函数依赖于另一个非键属性

在完成第 11 章和第 12 章后,再进行这些练习。

  1. 什么是规范化?
  2. 何时表处于 1NF?
  3. 何时表处于 2NF?
  4. 何时表处于 3NF?
  5. 识别和讨论图 12.2 中显示的依赖关系图中所示的每个依赖关系。图 12.2 用于问题 5,由 A. Watt 提供。
  6. 为了跟踪学生和课程,一所新学院使用图 12.3 中的表结构。绘制此表的依赖关系图。图 12.3 用于问题 6,由 A. Watt 提供。
  7. 使用刚刚绘制的依赖关系图,显示您将创建的表(以其第三范式形式)来解决遇到的问题。绘制修复后的表的依赖关系图。
  8. 一家名为 Instant Cover 的机构为苏格兰的酒店提供兼职/临时员工。图 12.4 列出了机构员工在各个酒店工作的时间。国民保险号码 (NIN) 对于每个员工都是唯一的。使用图 12.4 回答问题 (a) 和 (b)。图 12.4 用于问题 8,由 A. Watt 提供。
    1. 此表容易受到更新异常的影响。提供插入、删除和更新异常的示例。
    2. 将此表规范化为第三范式。说明所有假设。
  9. 填写空白
    1. ____________________ 产生较低的范式。
    2. 任何其值决定行内其他值的属性称为____________________。
    3. 不能进一步划分的属性被称为显示____________________。
    4. ____________________ 指的是存储在表行中的值所表示的详细程度。
    5. 关系表不能包含____________________ 组。

另见*附录 - 示例 ERD 练习*

参考书目

[编辑 | 编辑源代码]
  • Nguyen Kim Anh,*关系设计理论*。OpenStax CNX。2009 年 7 月 8 日。2014 年 7 月从 http://cnx.org/contents/606cc532-0b1d-419d-a0ec-ac4e2e2d533b@1@1 检索
  • Russell,Gordon。第 4 章 - 规范化。*数据库电子学习*。未注明日期。2014 年 7 月从 db.grussell.org/ch4.html 检索

参考资料

[编辑 | 编辑源代码]
华夏公益教科书