📜  数据库规范化介绍(1)

📅  最后修改于: 2023-12-03 15:26:08.094000             🧑  作者: Mango

数据库规范化介绍

什么是数据库规范化

数据库规范化是一种设计数据库的方式,它旨在减少重复数据,确保数据一致性和可靠性,并最大限度地提高查询性能。通过分解数据库表,从一张大表中创建多个较小的表并应用约束,以将数据分散到不同的表中,从而达到规范化的目的。

数据库规范化的好处

规范化可以带来以下好处:

  • 数据的一致性和可靠性:规范化可以确保每个数据只出现一次,从而消除了数据的冲突和不一致,提高了数据的可靠性和一致性。
  • 数据的完整性:规范化可以应用约束来强制执行数据的完整性,从而消除了数据的错误和不完整,提高了数据的完整性。
  • 查询的性能:规范化可以将数据分散到多个表中,从而改善查询性能。由于一些查询只需要访问少量表,所以它可以显著地提高查询速度。
  • 更好的设计:规范化可以强制扫描数据并更好地组织它们,从而促进更好的设计。
数据库规范化的三个范式

在数据库规范化中,有三个范式:

第一范式(1NF)

第一范式要求表中的每个列都是原子性的,即每个列中只有一个值。这意味着如果您的表中有一列包含了多个值,那么您的表就不符合1NF。在1NF中,表的每行都必须具有唯一标识符,通常是一个主键。

例如,以下表不符合1NF:

| 项目编号 | 项目名称 | 开始日期 | 结束日期 | |:-------:|:------:|:-------:|:-------:| | 001 | 项目1 | 2019-01 | 2019-02 | | 002 | 项目2 | 2019-03 | 2019-04 | | 003 | 项目3 | 2019-05 | 2019-06 | | 004 | 项目4 | 2019-07 | 2019-08 |

在这个表中,开始日期和结束日期是一列而不是两列,因此这个表不符合1NF。为了使其符合1NF,可以拆分开始和结束日期为两个单独的列,如下所示:

| 项目编号 | 项目名称 | 开始年份 | 开始月份 | 结束年份 | 结束月份 | |:-------:|:------:|:-------:|:-------:|:-------:|:-------:| | 001 | 项目1 | 2019 | 01 | 2019 | 02 | | 002 | 项目2 | 2019 | 03 | 2019 | 04 | | 003 | 项目3 | 2019 | 05 | 2019 | 06 | | 004 | 项目4 | 2019 | 07 | 2019 | 08 |

现在,每个列都只包含一个值,因此这个表符合1NF。

第二范式(2NF)

第二范式要求表中的每个非主键列都依赖于主键。换句话说,如果一张表有一个组合主键,则每个非主键列都必须依赖于整个组合主键而不是部分组合主键。如果某个非主键列只依赖于表中的一部分主键,那么这个表就不符合2NF。

例如,以下表不符合2NF:

| 订单编号 | 产品编号 | 产品名称 | 产品价格 | 订单日期 | |:-------:|:-------:|:--------:|:--------:|:-------:| | 001 | 001 | 产品1 | 100.00 | 2019-01 | | 001 | 002 | 产品2 | 200.00 | 2019-01 | | 002 | 001 | 产品1 | 100.00 | 2019-02 | | 002 | 002 | 产品2 | 200.00 | 2019-02 | | 003 | 003 | 产品3 | 300.00 | 2019-03 |

在这个表中,订单编号和产品编号是组合主键。产品名称和产品价格只依赖于产品编号,而不是整个组合主键。要使其符合2NF,可以拆分订单表和产品表,如下所示:

订单表:

| 订单编号 | 订单日期 | |:-------:|:-------:| | 001 | 2019-01 | | 002 | 2019-02 | | 003 | 2019-03 |

产品表:

| 产品编号 | 产品名称 | 产品价格 | |:-------:|:--------:|:--------:| | 001 | 产品1 | 100.00 | | 002 | 产品2 | 200.00 | | 003 | 产品3 | 300.00 |

现在,每个非主键列都依赖于主键,所以它符合2NF。

第三范式(3NF)

第三范式要求表中的每个非主键列都不依赖于其他非主键列。换句话说,一个表中的每个非主键列都应该只与主键有关。如果一个非主键列依赖于其他非主键列,那么这个表就不符合3NF。

例如,以下表不符合3NF:

| 订单编号 | 产品编号 | 产品名称 | 产品价格 | 类别名称 | |:-------:|:-------:|:--------:|:--------:|:-----:| | 001 | 001 | 产品1 | 100.00 | 电子类 | | 001 | 002 | 产品2 | 200.00 | 电子类 | | 002 | 001 | 产品1 | 100.00 | 食品类 | | 002 | 002 | 产品2 | 200.00 | 食品类 | | 003 | 003 | 产品3 | 300.00 | 电子类 |

在这个表中,类别名称不依赖于订单编号或产品编号,而是依赖于产品名称和产品价格。因此,这个表不符合3NF。要使其符合3NF,可以创建一个分类表,如下所示:

订单表:

| 订单编号 | 产品编号 | 产品名称 | 产品价格 | |:-------:|:-------:|:--------:|:--------:| | 001 | 001 | 产品1 | 100.00 | | 001 | 002 | 产品2 | 200.00 | | 002 | 001 | 产品1 | 100.00 | | 002 | 002 | 产品2 | 200.00 | | 003 | 003 | 产品3 | 300.00 |

分类表:

| 产品名称 | 产品价格 | 类别名称 | |:--------:|:--------:|:-----:| | 产品1 | 100.00 | 电子类 | | 产品2 | 200.00 | 电子类 | | 产品3 | 300.00 | 电子类 | | 产品1 | 100.00 | 食品类 | | 产品2 | 200.00 | 食品类 |

现在,每个非主键列都不依赖于其他非主键列,每个表都符合3NF。

总结

数据库规范化可以确保数据的一致性和可靠性,并最大限度地提高查询性能。通过分解大表,创建多个较小的表并应用约束,可以将数据分散到不同的表中,从而实现规范化的目的。在规范化中,有三个范式(1NF,2NF和3NF),每个范式都是序列化的,需要依次满足前一个范式才能满足后一个范式。