什么是第二范式(2NF)?

在处理数据库时,常常会遇到诸如冗余数据和不一致更新等问题。第二范式是一个数据库规范化步骤,它在第一范式(1NF)的基础上构建,以创建更清洁和高效的表格。

了解2NF对于任何从事数据库设计或数据管理工作的人都至关重要,它为像第三范式(3NF)这样的更高规范化形式奠定了基础。在本文中,我们将探讨2NF的工作原理,以及如何转换表格以满足2NF的要求,并提供实际示例。我们还将讨论2NF的优缺点,以及最适合的使用场景。

理解第二范式

第二范式是一个专注于消除部分依赖关系的数据库规范化步骤。它是由关系数据库的先驱埃德加·科德(Edgar F. Codd)引入的,作为他规范化工作的一部分。

在表格能够达到2NF之前,必须满足第一范式的规则:

  • 原子性:每个单元格必须包含一个单一的值(不能有重复的组或数组)。
  • 唯一行:表必须有一个明确的主键。

第二范式进一步增加了一条规则:消除部分依赖

部分依赖发生在一个非主属性(不是任何候选键的列)仅依赖于复合键的一部分而不是整个键时。2NF规则确保所有非主属性依赖于整个主键,而不仅仅是其中的一部分。在表中保留部分依赖意味着冗余数据可能会进入数据库,在更新或删除过程中可能导致低效和潜在的不一致。

理论本身可能有点枯燥,让我们看一个实际的例子。

以下是 Datacamp 学生的课程注册表。

Student ID Course ID Course Name Instructor Name
1001 201 SQL基础 Ken Smith
1002 202 Python简介 Merlin O’Donnell
1001 202 Python简介 Merlin O’Donnell

这里,主键是学生ID课程ID的组合。然而,非主属性课程名称课程费用仅依赖于课程ID,而不是整个键。这违反了2NF。

将表分解为达到2NF的步骤:

为确保表符合2NF的规则,您需要:

  1. 识别所有候选键:确定能唯一标识表中行的属性最小集合。这些就是您的候选键。
  2. 确定函数依赖关系:识别表中的所有函数依赖关系。具体来说,查找那些非主属性(不是任何候选键的一部分)仅依赖于复合键的一部分的依赖关系。
  3. 消除部分依赖:对于每个部分依赖:
    • 将依赖属性与其依赖的键的部分放入新表中。
    • 确保新表具有唯一的主键。
  4. 重复直到没有部分依赖剩余:确认所有表中每个非主属性是否完全依赖于其相应的主键。

实践中第二范式的示例

现在让我们看两个示例。

示例1:课程报名表

早些时候,我们看到了以下课程报名表:

Student ID Course ID Course Name Instructor Name
1001 201 SQL基础 Ken Smith
1002 202 Python入门 Merlin O’Donnell
1001 202 Python入门 Merlin O’Donnell

让我们按照前一节中概述的步骤进行。

1. 确定我们的候选键。

在这种情况下,候选键是由学生ID课程ID组成的复合键。这个唯一的组合识别表中的每一行。

2. 确定我们的功能依赖关系

课程名称讲师名称 依赖于 课程ID,而不是完整的复合键(学生ID课程ID)。这是一个部分依赖,因为这些属性仅依赖于复合键的一部分。

3. 消除部分依赖

我们需要将仅依赖于关键部分(课程名称教师姓名)的属性移至一个仅基于课程ID的新表中。

分解后,我们的新表如下:

课程报名表

Student ID Course ID
1001 201
1002 202
1001 202

课程详情表

Course ID Course Name Instructor Name
201 SQL基础 Ken Smith
202 Python入门 Merlin O’Donnell

如果您想动手创建自己的数据库,请查看我们的PostgresQL课程。如果您有一定的基础,可以尝试这个雪花数据建模入门,其中涵盖了实体关系和维度建模等概念。

示例2:订单表

我们将从这个订单表开始。尝试按照我们上面概述的步骤,自行分解这个表格!

Order ID Product ID Order Date Product Name Supplier Name
1 201 2024-11-01 笔记本电脑 TechSupply
1 202 2024-11-01 鼠标 TechSupply
2 201 2024-11-02 笔记本电脑 TechSupply
3 203 2024-11-03 键盘 KeyMasters

1. 确定我们的候选键

订单ID产品ID的组合唯一标识每一行,使得(订单ID产品ID)成为复合候选键。因为没有单个列可以唯一标识行:

  • 订单编号本身并不唯一,因为同一个订单中可以包含多个产品。
  • 产品编号本身并不唯一,因为同一产品可能出现在不同的订单中。

这意味着 (订单 ID, 产品 ID) 也是我们的主键。

2. 确定我们的功能依赖关系

订单日期取决于订单编号(而不是完整的复合键)。这是部分依赖。

产品名称供应商名称 依赖于 产品ID(而不是完整的复合键)。这些也是部分依赖。

3. 消除部分依赖

我们需要将表拆分为更小的表,每个表解决一个逻辑依赖。

首先,我们将创建一个订单信息表,包含与订单ID相关的信息。

订单表

Order ID Order Date
1 2024-11-01
2 2024-11-02
3 2024-11-03

然后,我们创建一个表,包含与产品ID相关的信息。

订单表

Product ID Product Name Supplier Name
201 笔记本电脑 科技供应
202 鼠标 科技供应
203 键盘 键大师

原始表现在简化为仅包含复合键以及订单与产品之间的关系。

Order ID Product ID
1 201
1 202
2 201
3 203

现在,我们的数据库处于第二范式,因为 1) 所有部分依赖关系已被消除,且 2) 非主属性完全依赖于各自的主键。

何时实施第二范式

那么,为什么你应该将数据库重构为第二范式(2NF)?它单独足够吗,还是应该更进一步,追求第三范式(3NF)?

第二范式的好处和局限性

第二范式提供了几个优点,使其成为数据库规范化过程中的一个有用步骤:

  • 增强的数据完整性:通过消除部分依赖,2NF 最小化插入、更新和删除异常,从而导致更可靠的数据库。
  • 减少冗余:2NF 减少数据重复,优化存储使用并简化数据维护。
  • 改进的数据结构:通过创建更清晰、更高效的数据库设计,为进一步规范化(如过渡到第三范式)奠定了基础。

但它确实存在一些限制:

  • 增加的复杂性:为了满足2NF而分解表可能会使设计过程变得更加复杂,特别是在处理复合键和依赖关系时。
  • 附加联接:拆分表可能需要在查询中进行更多的联接,在有大型数据集或复杂查询的系统中可能会影响性能 – 详细信息如下。
  • 残余冗余:虽然2NF减少了部分依赖关系,但它并未解决传递依赖关系,直到在3NF中解决之前仍会存在一些冗余。

第二范式的性能考虑

将表进行分解以消除部分依赖关系可能直接影响数据库性能。一方面,实现2NF可以减少数据冗余并提高一致性,减少在插入、更新或删除操作期间的异常。另一方面,规范化可能会增加表的数量,这意味着在检索相关数据时需要进行额外的连接。这可能会影响大型数据集的查询性能。

为了确保您的规范化数据库保持高性能,请确保遵循以下最佳实践:

  • 索引:使用索引加快分解表之间的连接速度。
  • 查询优化: 优化查询以最小化额外连接的成本。
  • 混合方法: 在性能重要的领域,如报表表中,将规范化与去规范化结合起来。
  • 定期监控: 使用性能分析工具持续评估数据库性能,以发现潜在问题。

2NF只是实现第三范式的过渡步骤吗?

在大多数情况下,数据库设计师努力实现第三范式,因为它能够进一步减少冗余并提高整体数据完整性。然而,实现3NF通常需要额外的工作,例如创建更多的表和关系,这可能会在查询执行中引入复杂性和性能权衡。

在某些情况下,仅使用第二范式可能就足够了。如果简洁性和快速实施是优先考虑的因素,例如在小规模项目、原型设计或数据冗余最小的情况下,2NF可能足够。例如,在所有属性已经完全依赖于一个简单主键的系统中,实现2NF可能会实现减少部分依赖的主要目标,而无需进一步规范化。

超越第二范式:迈向第三范式

如果您想进一步规范化数据库,可以继续重构表以达到第三范式。

3NF通过解决传递依赖来构建在2NF之上 – 即非关键属性依赖于其他非关键属性而不是主键的情况。这种进展确保每个属性直接依赖于主键而不依赖于其他内容。

例如,在跟踪课程注册情况的表中:

  • 第二范式: 确保诸如课程名称和学生名称等属性完全依赖于各自的主键(例如,学生ID课程ID)。这消除了部分依赖,即非主键属性仅依赖于复合键的一部分。
  • 3NF:确保如讲师详细信息或部门信息等属性存储在单独的表中,消除传递依赖。

3NF 适用于数据完整性和效率至关重要的更复杂系统,特别是当数据量增长时。如果你想了解更多关于 3NF 及其更严格形式 BCNF 的信息,请查看我们的 什么是第三范式? 文章。

结论

第二范式是数据库规范化的重要步骤,弥合了 1NF 和更高形式如 3NF 之间的差距。通过消除部分依赖,2NF 减少了冗余,提高了数据的可靠性。虽然它可能增加一些复杂性,但改进的数据完整性和简化的维护所带来的好处,使其成为有效数据库设计的关键部分。

如果您准备进一步提升自己的技能,可以探索我们的 数据库设计 课程,以加深对规范化技术及其实际应用的理解。您还可以通过我们的 SQL 助理认证 来验证您的 SQL 和数据库管理技能,并向潜在雇主展示您的专业知识!

最后,我想说,如果您是企业中的决策者,并且知道您需要在创建 更干净、更高效的数据库 上付出努力,请考虑提交 DataCamp for Business 演示请求。我们可以帮助提升您团队的能力,以便您能够创建可扩展的数据库系统,从而推动业务效率和创新。我们甚至可以创建量身定制的学习路径和定制课程。

Source:
https://www.datacamp.com/tutorial/second-normal-form