数据库管理系统中的第二范式 (2NF)
范式确保表中的数据保持结构化和高效。在达到第一范式 (1NF) 之后,规范化过程中的下一步是第二范式 (2NF),它通过解决部分依赖来帮助消除某些类型的冗余。阅读本章以详细了解什么是 2NF 以及如何应用它。
什么是第二范式 (2NF)?
2NF 的规则很简单。根据关系数据库之父 E. F. Codd 的定义,
- 表必须已经处于 第一范式 (1NF)。
- 表中不应存在 部分依赖。
让我们进一步分解这些规则 −
- 1NF 要求 − 这意味着表不应具有多值属性。每个单元格应只有一个值。
- 无部分依赖 − 部分依赖发生在非主属性仅依赖于复合 candidate key 的一部分,而不是整个键时。
为了更好地理解,让我们详细说明一些重要术语 −
- Candidate Key − 可以唯一标识每一行的最小属性集。
- Prime Attributes − 候选键的一部分的属性。
- Non-Prime Attributes − 不属于任何候选键的属性。
什么是部分依赖?
部分依赖 存在于非主属性仅依赖于复合 candidate key 的一部分时。它会导致数据库中的冗余和异常。
部分依赖示例
考虑以下表 −
| Customer ID | Store ID | Location |
|---|---|---|
| 1 | 1 | Delhi |
| 2 | 1 | Delhi |
| 3 | 2 | Bangalore |
| 4 | 3 | Mumbai |
在这种情况下,
- Candidate Key − Customer ID 和 Store ID 的组合唯一标识每一行。
- Prime Attributes − Customer ID, Store ID
- Non-Prime Attribute − Location
仔细观察,属性 "Location" 仅依赖于 "Store ID"。例如,无论 Store ID 为 1,位置都是 Delhi。这违反了 2NF 的第二条规则,因为 Location 不依赖于整个复合键 (Customer ID, Store ID)。
如何将表转换为 2NF?
每当表违反 2NF 时,解决方案是将它拆分为更小的表。我们称此过程为 "Decomposition"。让我们通过上述示例来看看它是如何工作的。
步骤 1:拆分表
我们将表拆分为两个更小的表 −
- 一个表存储复合键及其主属性。
- 另一个表存储部分依赖。
步骤 2:识别键
- 在 Customer Table 中,candidate key 仍然是 Customer ID, Store ID。
- 在 Store Table 中,主键是 Store ID。
现在,非主属性 Location 完全依赖于其表中的 candidate key (Store ID)。这确保了两个表都处于 2NF。
实现 2NF 的一般步骤
以下是将任何表符合 2NF 的一般步骤 −
- 识别 Candidate Key − 使用函数依赖来找到所有可能的 candidate key。
- 分类属性 − 主属性是 candidate key 的一部分。非主属性是其他所有属性。
- 检查部分依赖 − 如果任何非主属性仅依赖于复合 candidate key 的一部分,则为部分依赖。
- 拆分表 − 创建单独的表来解决部分依赖。
另一个示例:函数依赖
让我们探索一个更复杂的带有函数依赖的示例。
表和函数依赖
我们有一个关系:{A, B, C, D, E, F},具有以下依赖 −
- C → F
- E → A
- E, C → D
- A → B
步骤 1:识别候选键
要找到候选键,我们必须查看函数依赖的右侧(RHS):{F, A, D, B}。不在 RHS 上的属性(E 和 C)必须是候选键的一部分。
从 E, C 开始 −
- E → A
- C → F
- E, C → D
- A → B
因此,E, C 的闭包覆盖了所有属性:{E, C, A, F, D, B}。所以,候选键是 {E, C}。
步骤 2:主属性和非主属性
- 主属性 − E, C。
- 非主属性 − A, B, D, F。
步骤 3:检查部分依赖
部分依赖 发生时 −
- 函数依赖的左侧(LHS)是候选键的真子集。
- RHS 是非主属性。
在我们的示例中,
- C → F:C 是 {E, C} 的真子集,且 F 是非主属性。存在部分依赖。
- E → A:E 是 {E, C} 的真子集,且 A 是非主属性。存在部分依赖。
步骤 4:拆分表
在这一步,为了消除部分依赖,我们将表分成更小的表 −
派生的表如下所示 –
每个表都满足 2NF,因为所有非主属性完全依赖于各自表的候选键。
2NF 的关键概念
以下是 2NF 的关键概念 –
- 主属性 − 候选键的一部分。
- 非主属性 − 不是任何候选键的一部分。
- 部分依赖 − 非主属性依赖于复合候选键的一部分。
- 完全函数依赖 − 非主属性依赖于整个候选键。
结论
在本章中,我们详细解释了第二范式 (2NF) 的概念以及如何在关系数据库中处理部分依赖。我们从 2NF 的基本规则开始,强调了首先实现 1NF 的重要性。
通过详细示例,我们探讨了部分依赖的概念,并演示了如何将表拆分成更小的表以消除冗余。通过确保 2NF,我们通过减少数据冗余使数据库更高效,并为更高级别的规范化奠定基础。