1 范式的基本概念
设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小。没有冗余的数据库未必是最好的数据库, 有时为了提高运行效率,就必须降低范式标准,适当保留冗余数据。
函数依赖
比如描述一个学生的关系,可以有学号(Sno),姓名(Sname)、系名(Sdept)等几个属性。由于一个学号对应一个学生,一个学生只在一个系学习。因此,学号确定以后,学生的姓名和其所在的系的值 也就被唯一的确定了。这种属性间的依赖关系,类似于数学中的 y=f(x),自变量x确定以后,相应的函数值y也就唯一确定了。
也就是 Sname=f(Sno),Sdept=f(Sno),即Sno函数决定Sname,Sno函数决定Sdept。或者说,Sname和Sdept函数依赖于Sno。记作 Sno→Sname,Sno→Sdept。
X→Y,Y→Z,则称为Z对X传递函数依赖。记为
X→Y,但Y不包含X,则称X→Y是非平凡的函数依赖。如:关系R(Sno, Cno, Grade),依赖关系(Sno, Cno)→Grade是非平凡函数依赖。
X→Y,但Y包含X,则称X→Y是平凡的函数依赖。如:关系R(Sno, Cno),依赖关系(Sno, Cno)→Sno,(Sno, Cno)→Cno都是平凡函数依赖。
完全函数依赖:每一个非主属性,函数依赖于主键中的全部属性,而不能仅依赖主键一部分的属性。因为主键可能有多个属性构成,比如主键有三个属性,某个非主属性仅依赖主键的三个属性中的两个,那么就不能被称为完全函数依赖。
部分函数依赖:X→Y,但Y不完全函数依赖于X,则称Y对X部分函数依赖。
码(key)
关系模式R<U,F>。关系名R,一组属性U,属性组U上的一组数据依赖F。
设K为R中的属性或属性组合。若U完全函数依赖于K,则称K为R的候选码。候选码可能多于一个,则选定其中一个为主码(主键)。
例如一个学生,身份证可以唯一表示一个学生,学号也可以唯一标识一个学生,(身份证,学号)这个集合可以唯一标识一个学生。我们可以选学号来作为这个学生的主键,那么学号、(身份证、学号)就是候选码。
包含在任何一个候选码中的属性,称为主属性。不包含在任何码中的属性称为非主属性或非码属性。
最简单的情况,单个属性是码。最极端的情况,整个属性组U是码,称为全码。
外码:一个属性(或属性组),它不是码,但是它别的表的码,它就是外码。
第一范式(1NF)
定义:数据库表的每一列(也称为属性)都是不可分割的原子数据项
学生表(学号,姓名,系名,系主任,课名,学分,考试成绩)
第二范式(2NF)
定义: 在1NF基础上,消除 非码属性 对码的部分函数依赖
学生表(学号,姓名,身份证号,生日,系名,系主任,课名,选修内容,学分,考试场次(期中/期末),成绩)
码:学号,课名,选修内容
候选属性:学号,课名,选修内容,身份证号
对码的全部依赖:
(学号,课名,选修内容)——>(考试场次,成绩)
对码部分依赖:
- 姓名|身份证号|学分——>(学号,课名,选修内容)
进行拆分 - 学生表(学号,姓名,身份证号,生日,系名,系主任)
- 课程(课名,学分)
- 选课(学号,课名,选修内容,考试场次,成绩)
第三范式(3NF)
定义: 在2NF基础上,消除非码属性对候选码的传递函数依赖
非码属性对候选码的传递依赖:
- 学号 ——> 系名 系名——>系主任 => 学号——>系主任
进行拆分:
学生表(学号,姓名,身份证号,生日,系名)
系表 (系名,系主任)
BCNF
- 定义:在3NF基础上,消除主属性对码的部分函数依赖和传递函数依赖
假设仓库管理关系表为StorehouseManage(仓库ID,存储物品ID,管理员ID,数量),且有一个管理员只在一个仓库工作;
一个仓库可以存储多种物品。这个数据库表中存在如下决定关系:
(仓库ID,存储物品ID)→(管理员ID,数量) (管理员ID,存储物品ID)→(仓库ID,数量)
在 3NF 的基础上消除主属性对于码的部分与传递函数依赖。
- 仓库(仓库名,管理员)
- 库存(仓库名,物品名,数量)
4NF
- 定义:在BCNF的基础上,消除非平凡且非函数依赖的多值依赖。
非平凡且非函数依赖的多值关系:
学号,课名,选修内容,考试场次,成绩
学号,课名——>选修内容 ,1对多
函数
学号,课名,选修内容——>考试场次, 多对多
进行拆分
关系表1(id1,学号,课程)
关系表2(id2,选修内容)
关系表2 (id3,id2,考试场次,成绩)
5NF
- 定义:在4NF的基础上,消除不是由候选码所蕴含的连接依赖。