关系范式使用一套标准来规约数据库表结构中属性之间的依赖关系,目的是出减少数据库中数据冗余,SQL操作异常等。
关系范式有:第一范式、第二范式、第三范式、BCNF范式、第四范式、第五范式。
同时想要达到高层关系范式必须先达到低层的所有范式:
1NF ⊂ 2NF ⊂ 3NF ⊂ BCNF ⊂ 4NF ...
现代数据库最多只能达到第三范式。同时并不是范式越高越好。
函数依赖
关系范式主要通过函数依赖关系来判定
函数依赖形式化表达
X -> Y 记作 X 决定Y 或 Y依赖于X。即表结构中的非主属性依赖于主属性,主属性决定非主属性
X !-> Y 或 X -\-> Y 记作 X不决定Y 或 Y 不依赖于X
完全函数依赖
定义:X 和 Y 为关系R的属性集,有 X -> Y ,且X中的任何真子集 X' 都有 X' !-> Y(x的任何子集无法单独决定y)。则称 Y完全依赖于X 或 X所有子集决定了Y。
R(学号,课程号,学生课程成绩)在此关系中存在如下的函数依赖
(学号,课程号) -> 学生课程成绩
(学号) !-> 学生课程成绩
(课程号) !-> 学生课程成绩
也就是说 X 的子集 X'不能决定Y (单独的学号或课程号),需要 X 整个属性集合才能决定 Y (这里使用学号和课程号确定一个课程成绩)
部分函数依赖
定义:相同条件下 X'存在一个真子集满足 X' -> Y 。则称为 Y部分依赖于X 或 X部分子集决定了Y
部分函数依赖 与 完全函数依赖 是对立的,即 X 的子集就能决定 Y R(学号 身份证号 姓名) 在此关系中存在如下的函数依赖(注:例子不是特别恰当)
1. X(学号,身份证号) -> 姓名
2. X'(学号) -> 姓名
3. X'(身份证号) -> 姓名
这里X集合为 (学号,身份证号),X的子集(学号)也可以决定姓名这个属性。也就是 X 的子集 X' 可以决定 Y,则存在部分函数依赖
传递函数依赖
定义:X、Y、Z 在同一关系R中属性集,X -> Y ,Y -> Z,Y !-> X 此时Z传递依赖于X(X间接决定Z)
R( 教师号,课程号,姓名,课程名称 ) 假设课程和教师是 1 : N 的关系,关系中就存在如下依赖:
教师号 -> 课程号
课程号 -> 课程名称
课程号 !-> 教师号
存在 课程名称 传递函数依赖于 教师号
若没有 Y !-> X 此条件说明 X <-> Y(相互依赖) ,那么这时 X -> Z (Z直接依赖于X),例如部分函数依赖中的例子:学号 -> 身份证号,身份证号 -> 姓名,身份证号 -> 学号。那么此时姓名直接依赖于学号,而不是传递函数依赖。
关系规范化过程(范式)
第一范式 (1NF)
定义:属性不可再分。
第一范式规约了一个关系的最基本结构。也就是说在关系型数据库中创建一张数据表,如果该表是可操作的,该表(关系)一定满足第一范式。
第二范式 (2NF)
定义:同一关系中 非主属性 都完全函数依赖于 主属性 ,不存在部分函数依赖。
不可以存在与主属性无关的属性
第三范式 (3NF)
定义:同一关系中非主属性都不传递函数依赖于候选关键字
如果非主属性不直接依赖于主属性(传递),一般这个中间属性可以分离为另一个关系的主属性
BCNF(Boyce-Codd Normal Form)
定义:同一关系 F 中存在 X -> Y ( X , Y 为 F 中的属性集) 其中 X 必须包含 候选关键字 或 必须是 超码
如何得到一组具有BCNF范式的关系
可以看得出来第二第三范式都是用来规定非主属性和键/码之间的关系,但是在某些情况下即使关系达到了第三范式依然可能,存在插入删除等异常。
BCNF:就在达到第三范式的基础上,对 键 与 键 之间的完全函数依赖、传递函数依赖关系进行规约。可以认为BCNF就是在第三范式的基础上进行优化。因此达到这一层的范式称为并没有直接取名为第四范式,而是基于第三范式的优化。