数据库范式(关系型数据库)

通过规范来解决数据冗余以及一些操作异常的情况。在实际生活中,追求最高的范式并不一定是最好的选择,要考虑多方面因素,如查询速度,数据量等等,尽量选择一个满足需求的,合理的结构

目前关系数据库有六种范式:1NF,2NF,3NF,BCNF,4NF,5NF

第一范式(1NF)

要求数据库表的每一列都是不可分割的原子数据项,即实体中的某个属性有多个值时,必须拆分为不同的属性,例如:

用户信息表

编号 姓名 年龄 地址
1 小王 23 浙江省杭州市拱墅区湖州街51号

当实际需求对地址没有特定的要求下,这个用户信息表的每一列都是不可分割的。但是当实际需求对省份或者城市有特别要求时,这个用户信息表中的地址就是可以分割的,改为:

用户信息表

编号 姓名 年龄 省份 城市 详细地址
1 小王 23 浙江省 杭州市 拱墅区湖州街51号

好处

  • 表结构相对清晰
  • 易于查询

第二范式(2NF)

主键与非主键之间是完全函数依赖关系。即数据库表中的每一列都和主键的所有属性相关,不能只和主键的部分属性相关
完全函数依赖:有属性集 X,Y,通过 X 中的所有属性能够推出 Y 中的任意属性,但是 X 的任何真子集,都不能推出 Y 中的任何属性,例如:

学生课程表

学生编号 课程编号 学生名称 课程名称 所在班级 班主任
S1 C1 小王 计算机导论 计算机3班 陈老师
S1 C2 小王 数据结构 计算机3班 陈老师
S2 C1 小马 计算机导论 软件1班 李老师

将学生编号和课程编号作为主键,能确定唯一一条数据,但是学生名称只跟学生编号有关,跟课程编号无关,即不满足完全函数依赖,改为:

学生表

学生编号 学生名称 所在班级 班主任
S1 小王 计算机3班 陈老师
S2 小马 软件1班 李老师

课程表

课程编号 课程名称
C1 计算机导论
C2 数据结构

学生课程关系表

学生编号 课程编号
S1 C1
S1 C2
S2 C1

好处

  • 相对节约空间,当学生表和课程表属性越多,效果越明显
  • 解决插入异常,当新增一门课程时,原表因为没有学生选课,导致无法插入数据
  • 解决更新繁琐,当更改一门课程名称时,原表要更改多条数据
  • 解决删除异常,当学生学完一门课,原表若要清空学生上课信息,课程编号与课程名称的关系可能会丢失

第三范式(3NF)

任何非主属性不依赖于其它非主属性,即消除传递函数依赖(在 2NF 基础上)
传递函数依赖:有属性集 X,Y,Z,满足 $X \Rightarrow Y,X \not\subset Y,Y \nRightarrow X,( X \bigcup Y ) \bigcap Z = \emptyset,Y \Rightarrow Z$ 时,则 Z 传递函数依赖于 X,例如:

学生表

学生编号 学生名称 所在班级 班主任
S1 小王 计算机3班 陈老师
S2 小马 软件1班 李老师

学生编号作为主键满足第二范式(2NF)。通过学生编号 $\Rightarrow$ 所在班级 $\Rightarrow$ 班主任,所以班级和班主任之间存在依赖关系,改为:

学生表

学生编号 学生名称 所在班级
S1 小王 计算机3班
S2 小马 软件1班

班级表

所在班级 班主任
计算机3班 陈老师
软件1班 李老师

好处

  • 相对节约空间
  • 解决更新繁琐
  • 解决插入异常,当班级分配了老师,还没分配学生的时候,原表将不可插入数据
  • 解决删除异常,当学生毕业后,若要清空学生信息,班级和老师的关系可能会丢失

巴斯-科德范式(BCNF)

在3NF基础上,消除主属性之间的传递函数依赖,例如:

配件表

仓库号 配件号 职工号 配件数量
W1 P1 E1 10
W1 P2 E1 10
W2 P1 E2 20

有以下约束:

  • 一个仓库有多个职工
  • 一个职工只在一个仓库
  • 一种配件可以放多个仓库
  • 一个仓库,一个职工管理多个配件,一种配件由唯一一个职工管理

由此,将(仓库号,配件号)作为主键,满足 3NF,但是(仓库号,配件号)$\Rightarrow$ 职工号 $\Rightarrow$ 仓库号,造成传递函数依赖,改为:

仓库表

仓库号 职工号
W1 E1
W2 E2

工作表

职工号 配件号 配件数量
E1 P1 10
E1 P2 10
E2 P1 20

好处:解决一些冗余和一些异常情况
不足:丢失一些函数依赖,如丢失(仓库号,配件号)$\Rightarrow$ 职工号,无法通过单表来确定一个职工号

第四范式(4NF)

当一个表中非主属性相互独立时(即在 3NF 基础上),这些非主属性不应该有多值,例如:

客户联系方式

客户编号 固定电话 移动电话
10 88-123 151
10 80-123 183

一个用户拥有多个固定电话和移动电话,给表的维护带来很多麻烦。比如增加一个固定电话,那么移动电话这一栏就较难维护,改为:

客户电话表

客户编号 电话号码 电话类型
10 88-123 固定电话
10 80-123 固定电话
10 151 移动电话
10 183 移动电话

好处:解决一些异常,使表结构更加合理

第五范式(5NF)

在关系模式 R 中,每一个连接依赖均有 R 的候选码所隐含。即连接时,所连接的属性都是候选码,例如:

销售表

销售人员 供应商 产品
S1 V1 P1
S2 V2 P2
S1 V1 P1
S2 V2 P2

要想找到某一条数据,必须以(销售人员,供应商,产品)为主键,改为:

销售人员_供应商表

销售人员 供应商
S1 V1
S2 V2

销售人员_产品表

销售人员 产品
S1 P1
S2 P2

供应商_产品表

供应商 产品
V1 P1
V2 P2

好处:解决某些异常操作