数据库管理系统中的范式
规范化是组织数据库中数据以减少冗余并提高数据一致性的过程。主键在组织数据库中的信息方面非常重要。它们有助于确保表中的每一行都有唯一的标识,从而避免任何信息混淆或丢失。
在本文中,我们将讨论数据库规范化的不同范式。
规范化
规范化是组织数据库中数据以避免数据冗余、插入异常、更新异常和删除异常的过程。
规范化是组织数据库中数据以最大限度地减少冗余和依赖关系的过程。在数据库设计中,根据表的主键存在不同的范式。这些包括:
第一范式 (1NF)
1NF 要求表中的每一列都包含原子值,并且每一行都有唯一的标识。这意味着表不能包含重复的组或数组作为列,并且每一行都必须具有唯一的主键。
示例
如果每一列都包含原子值,并且每一行都有唯一的标识,则该表处于 1NF。例如,一个列出客户及其电话号码的表:
客户ID |
姓名 |
电话号码 |
---|---|---|
1 |
John |
555-1234, 555-5678 |
2 |
Jane |
555-9876 |
3 |
Michael |
555-5555 |
这违反了 1NF,因为“电话号码”列包含重复的组。
为了将此表规范化为 1NF,我们可以将“电话号码”列拆分为单独的行,并添加一个单独的主键列:
客户ID |
姓名 |
电话号码 |
---|---|---|
1 |
John |
555-1234 |
1 |
John |
555-5678 |
2 |
Jane |
555-9876 |
3 |
Michael |
555-5555 |
第二范式 (2NF)
2NF 在 1NF 的基础上,要求表中的每一列非主键列都完全函数依赖于主键。这意味着表不应该存在部分依赖,其中非主键列仅依赖于主键的一部分。
示例
如果每个非主键列都完全函数依赖于主键,则该表处于 2NF。例如,一个列出订单及其明细项的表:
订单ID |
客户ID |
客户姓名 |
商品ID |
商品名称 |
数量 |
---|---|---|---|---|---|
1 |
1 |
John |
1 |
衬衫 |
2 |
1 |
1 |
John |
2 |
裤子 |
1 |
2 |
2 |
Jane |
1 |
衬衫 |
1 |
2 |
2 |
Jane |
3 |
帽子 |
3 |
这违反了 2NF,因为“客户姓名”列仅依赖于主键的一部分(客户ID)。为了将此表规范化为 2NF,我们可以将其拆分为两个表:
订单ID |
客户ID |
商品ID |
数量 |
---|---|---|---|
1 |
1 |
1 |
2 |
1 |
1 |
2 |
1 |
2 |
2 |
1 |
1 |
2 |
2 |
3 |
3 |
客户ID |
客户姓名 |
---|---|
1 |
John |
2 |
Jane |
第三范式 (3NF)
3NF 在 2NF 的基础上,要求表中的每一列非主键列都不传递依赖于主键。这意味着表不应该存在传递依赖,其中非主键列依赖于另一个非主键列。
示例
为了进一步解释 3NF,让我们考虑一个列出客户订单的表的示例:
订单ID |
客户ID |
客户姓名 |
客户城市 |
订单日期 |
订单总额 |
---|---|---|---|---|---|
1 |
100 |
John Smith |
纽约 |
2022-01-01 |
100 |
2 |
101 |
Jane Doe |
洛杉矶 |
2022-01-02 |
200 |
3 |
102 |
Bob Johnson |
旧金山 |
2022-01-03 |
300 |
在此示例中,非主键列“客户城市”传递依赖于主键。也就是说,它依赖于“客户ID”(不是主键的一部分),而不是直接依赖于主键“订单ID”。为了使此表达到 3NF,我们可以将其拆分为两个表:
表 1:客户
客户ID |
客户姓名 |
客户城市 |
---|---|---|
100 |
John Smith |
纽约 |
101 |
Jane Doe |
洛杉矶 |
102 |
Bob Johnson |
旧金山 |
表 2:订单
订单ID |
客户ID |
订单日期 |
订单总额 |
---|---|---|---|
1 |
100 |
2022-01-01 |
100 |
2 |
101 |
2022-01-02 |
200 |
3 |
102 |
2022-01-03 |
300 |
现在,“客户城市”列不再传递依赖于主键,而是位于与主键具有直接关系的单独表中。这使得表符合 3NF。
Boyce-Codd 范式 (BCNF)
BCNF 是 3NF 的更严格形式,适用于具有多个候选键的表。BCNF 要求表中的每个非平凡依赖都是对候选键的依赖。这意味着表不应该存在非平凡依赖,其中非主键列依赖于另一个非主键列。BCNF 确保数据库中的每个表都是一个单独的实体,并消除了冗余。
示例
如果每个决定因素都是候选键,则该表处于 BCNF。换句话说,表中的每个非平凡函数依赖都必须在候选键上。例如,考虑一个列出书籍及其作者信息的表:
表:书籍
书籍ID |
书名 |
作者ID |
作者姓名 |
作者国籍 |
---|---|---|---|---|
1 |
罪与罚 |
100 |
陀思妥耶夫斯基 |
俄罗斯 |
2 |
了不起的盖茨比 |
101 |
F.斯科特·菲茨杰拉德 |
美国 |
3 |
傲慢与偏见 |
102 |
简·奥斯汀 |
英国 |
在此示例中,“作者ID”和“作者姓名”之间的函数依赖违反了 BCNF,因为它不在候选键上。为了使此表达到 BCNF,我们可以将其拆分为两个表:
表 1:作者
作者ID |
作者姓名 |
作者国籍 |
---|---|---|
101 |
陀思妥耶夫斯基 |
俄罗斯 |
101 |
F.斯科特·菲茨杰拉德 |
美国 |
102 |
简·奥斯汀 |
英国 |
表 2:书籍
书籍ID |
书名 |
作者ID |
---|---|---|
1 |
罪与罚 |
100 |
2 |
了不起的盖茨比 |
101 |
3 |
傲慢与偏见 |
102 |
现在,“作者姓名”和“作者国籍”列不再传递依赖于主键,并且该表处于 BCNF。
第四范式 (4NF)
4NF 在 BCNF 的基础上,要求表不应该存在多值依赖。当非主键列依赖于其他非主键列的组合时,就会发生多值依赖。例如,一个列出客户订单的表,其主键为订单ID,非主键列为客户ID和订单项,违反了 4NF,因为订单项依赖于订单ID和客户ID。
例如,一个列出订单及其产品的表,其中包含订单ID、产品ID和产品详细信息的列,违反了 4NF,因为产品详细信息依赖于订单ID和产品ID的组合。
示例
考虑以下订单和产品的表:
订单ID |
产品ID |
产品名称 |
产品描述 |
---|---|---|---|
1 |
100 |
Widget |
红色 Widget |
1 |
200 |
Widget |
蓝色 Widget |
2 |
100 |
Widget |
红色 Widget |
2 |
300 |
Thing |
绿色 Thing |
3 |
200 |
Widget |
蓝色 Widget |
3 |
300 |
Thing |
绿色 Thing |
在此表中,产品名称和描述都依赖于订单ID和产品ID,从而产生多值依赖。为了使表达到 4NF,我们可以将其拆分为三个表:
订单ID |
产品ID |
---|---|
1 |
100 |
1 |
200 |
2 |
100 |
2 |
300 |
3 |
200 |
3 |
300 |
产品ID |
产品名称 |
---|---|
100 |
Widget |
200 |
Widget |
300 |
Thing |
产品ID |
产品描述 |
---|---|
100 |
红色 Widget |
200 |
蓝色 Widget |
300 |
绿色 Thing |
规范化的优缺点
规范化的优点
减少数据冗余
提高数据一致性
简化数据库维护
提高查询性能
规范化的缺点
增加复杂性
降低读取性能
提高写入性能
增加存储空间
过度规范化
结论
因此,我们已经解释了数据库管理系统 (DBMS) 中规范化的概念及其在数据管理中的重要性。我们涵盖了数据库规范化的不同范式,包括 1NF、2NF、3NF、BCNF 和 4NF。我们解释了规范化如何帮助消除数据冗余、插入、更新和删除异常。我们还提供了不同范式中表的示例以及如何将其规范化为所需范式的示例。我们已经撰写了关于规范化在确保 DBMS 中数据一致性和准确性方面的重要性。