数据库规范化(范式)
为什么需要数据库规范化
单个关系的大型数据库可能会导致数据重复。数据重复可能会导致:
- 使关系非常大。
- 维护和更新数据并不容易,因为它涉及搜索相关的许多记录。
- 磁盘空间和资源的浪费和利用率低下。
- 错误和不一致的可能性增加。
总之:不容易维护,数据冗余,数据完整性受到影响
为了处理这些问题,我们应该分析冗余数据的关系并将其分解为更小、更简单、结构良好且满足所需属性的关系。规范化是将关系分解为具有较少属性的关系的过程。
范式的作用主要是为了消除这些异常现象。未能消除异常会导致数据冗余,并且随着数据库的增长可能会导致数据完整性和其他问题。
什么是数据库规范化
数据库规范化是数据库设计的一系列原理和技术,以减少数据库中数据冗余,增进数据的一致性。
现在数据库设计最多满足 3NF,普遍认为范式过高,虽然具有对数据关系更好的约束性,但也导致数据关系表数量增加,从而导致数据库 IO 更易繁忙,原来交由数据库处理的关系约束现更多在数据库使用程序(应用层)中完成。
范式是评价数据库模式规范化程度从低到高主要有:1NF、2NF、3Nf、BCNF、4NF、5NF。
第一范式 (1NF)
表的列的具有原子性,不可再分解, 第一范式(1NF)解决了列重复的问题。
第二范式 (2NF)
第二范式(2NF)是在第一范式(1NF)的基础上增加了两个新约束,每个表必须有一个主键,并且非主键列必须完全依赖于整个主键,而不能只依赖于主键的一部分。第二范式(2NF)解决了非主键列对主键的部分函数依赖问题。
第三范式 (3NF)
第三范式(3NF)是在第二范式(2NF)的基础上,要求一个数据库表中不包含已在其它表中已包含的非主键字段。即表的信息,如果能够被推导出来,就不应该单独的设计一个字段来存放(能尽量外键 join 就用外键 join)。为了满足第三范式往往会把一张表分成多张表。第三范式(3NF)解决了传递函数依赖问题。
巴克斯范式 (BCNF)
属于修正的第三范式,是防止主键的某一列会依赖于主键的其他列。当 3NF 消除了主属性对码的部分函数依赖和传递函数依赖称为 BCNF。
第四范式 (4NF)
非主属性不应该有多值。如果有多值就违反了第四范式。4NF 是限制关系模式的属性间不允许有非平凡且非函数依赖的多值依赖。
第五范式 (5NF)
第五范式消除了 4NF 中的连接依赖,表必须可以分解为较小的表,除非那些表在逻辑上拥有与原始表相同的主键。
相关概念解释
函数依赖
若在一张表中,在属性(或属性组)X 的值确定的情况下,必定能确定属性 Y 的值,那么就可以说 Y 函数依赖于 X,写作 X → Y。例如学生学号唯一的前提下,确定学号可以确定该学生姓名等其他消息。
部分函数依赖
如果 X→Y,并且存在 X 的一个真子集 X0,使得 X0→Y,则称 Y 对 X 部分函数依赖。比如学生基本信息表 R 中(学号,身份证号,姓名)当然学号属性取值是唯一的,在 R 关系中,(学号,身份证号)->(姓名),(学号)->(姓名),(身份证号)->(姓名);所以姓名部分函数依赖于(学号,身份证号)。
完全函数依赖
在一个关系中,若某个非主属性数据项依赖于全部关键字称之为完全函数依赖。比如学生基本信息表 R(学号,班级,姓名)假设不同的班级学号有相同的,班级内学号不能相同,在 R 关系中,(学号,班级)->(姓名),但是(学号)->(姓名)不成立,(班级)->(姓名)不成立,所以姓名完全函数依赖与(学号,班级)
传递函数依赖
设 X,Y,Z 是 U 的不同的属性子集,如果 X 确定 Y、Y 确定 Z,且有 X 不包含 Y,Y 不确定 X,(X∪Y)∩Z=空集合,则称 Z 传递函数依赖于 X。传递函数依赖会导致数据冗余和异常。传递函数依赖的 Y 和 Z 子集往往同属于某一个事物,因此可将其合并放到一个表中。比如在关系 R(学号 , 姓名, 系名,系主任)中,学号 → 系名,系名 → 系主任,所以存在非主属性系主任对于学号的传递函数依赖。