【数据库】通过实例理解数据库范式

138 阅读4分钟

「这是我参与2022首次更文挑战的第21天,活动详情查看:2022首次更文挑战」。

数据库范式是数据库原理的重要知识点,然而数据库范式的语言描述让人十分难以理解,本文将通过数据表的实例,帮助理解数据库范式。

基本概念

在设计关系型数据库时,需要遵从不同的规范要求,以设计出合理的关系型数据库。这些不同的规范要求就被称为不同的范式。

数据库范式最主要目的是为了消除重复数据,减少数据冗余,更好地组织数据库内的数据,让磁盘空间得到更有效的利用。但是范式会使查询变得相当复杂,在查询时需要更多的连接,一些复合索引的列由于范式化的需要被分割到不同的表中,导致索引策略不佳。

范式的描述中涉及一些名词,它们的解释如下:

  • 候选码:某些属性的组合可以在一个实体集中唯一地标识一个实体。如果对于某几个属性的组合,它们的任意真子集都不能唯一地标识一个实体,那么这样的最小组合称为候选码。
  • 主码(主键):从候选码中挑的一个属性最少的组合
  • 主属性:一个属性只要在任何一个候选码中出现过,这个属性就是主属性
  • 非主属性:与主属性相反,没有在任何候选码中出现过的属性,是非主属性

第一范式

所有的域都应该是原子性的,即数据库表的每一列都是不可分割的原子数据项,而不能是集合、数组、记录等非原子数据项

第一范式比较好理解,类比编程语言,数据库所有的列都应该是基本类型,如整型、字符串等,而不能是符合类型,如列表、字典等。

比如现在有一张学生表,每个学生的联系方式有两种:手机号码和电子邮箱,那么符合第一范式的表,不应该设计为 学生(学号,姓名,联系方式),然后在联系方式列保存一个保存了手机号码和邮箱的列表,因为这样联系方式列就不是不可分割的原子项目了,而应该设计为:学生(学号,姓名,手机,邮箱)

第二范式

符合第一范式,并且非主属性完全依赖于候选码

第二范式是在第一范式的基础上,要求属性完全依赖于主键。所有单关键字的数据库表都符合第二范式,因为不可能存在组合关键字。

比如现在有一张选课表:选课关系表(学号,课程号,成绩,学分) 。在这张表中,主键为 (学号,课程号)。而属性学分只与课程号相关,即属性部分依赖于主键。所以为了满足第二范式,需要对这张表进行拆分,拆分后的表为:选课关系表(学号,课程号,成绩)、课程表(课程号,学分)

第三范式

符合第一范式,并且每个非主属性既不部分依赖于码也不传递依赖于码

第三范式在第二范式基础上,消除了传递依赖

比如现在有一张学生表: 学生(学号,姓名,年龄,所在学院,学院地点) 。这张表的主键为 学号,为单关键字因此符合第二范式。但是根据学号可以知道学生所在学院,根据所在学院可以知道学院地点,即非主属性传递依赖于主属性,因此不符合第三范式。为了满足第二范式,需要对这张表进行拆分,拆分后的表为:学生(学号,姓名,年龄,所在学院)、学院(学院名,学院地点)

BC 范式

符合第一范式,且主键的任何一个真子集都不能决定于主属性

BC 范式在第三范式基础上,消除对主键子集的依赖

比如现在有仓库管理表 仓库管理(仓库号,存储物品号,管理员号,数量),其中,每个管理员管理一个仓库,每个仓库有唯一一个管理员,所以,该表的候选码可以为 (仓库号,存储物品号) 也可以为 (管理员号,存储物品号)。不管选择哪个作为候选码,数量都完全依赖于候选码,所以符合第三范式。从候选码中可以得出,该表的主属性有 仓库号,存储物品号,管理员号,由于管理员号依赖于仓库号(同样的,仓库号也依赖于管理员号),即主键的真子集决定于主属性,所以不符合 BC 范式。为了满足 BC 范式,这张表要给拆分为 仓库管理(仓库号,管理员号)、仓库表(仓库号,存储物品号,数量)