在我艰难的自考历程中,数据库系统原理考两次,现在也正经历第三次。现在看来之前没有过原因就是没有好好看书好复习,吸取前面的经验教训,这次可是把数据库系统原理好好的看了一遍,正是因为这一遍的学习,让我相信,数据库真的没有那么难。正因为前面的自考复习,所以在软考复习的时候这一块也轻松了很多。
所谓的范式就是为了减少数据库中数据冗余的过程。越高级别的范式数据冗余越小,反之则是数据冗余越大。所以可以把第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)按减少数据冗余的大小排列为:1NF<2NF<3NF<BCNF。从中可以得到较高级别的范式一定满足比它低级的范式要求,如:BCNF满足1NF、2NF、3NF的条件,BCNF一定是1NF、2NF、3NF ,3NF满足2NF、1NF的条件,所以3NF一定是1NF、2NF。
第一范式的要求在所有范式中是最低的,它只要求数据库表的每一列都是不可分割的原子数据项,不可以是集合、数组、记录等非原子数据项。也就是实体中的属性不可以是多值,如果是多值必须进行拆分。如下表就不符合第一范式,成绩统计这一项就有两个值,应把它拆分,这样才能变成第一范式。
|
成绩统计 |
|
系别 |
及格人数 |
不及格人数 |
中文 |
30 |
4 |
计算机 |
25 |
10 |
那第一范式应该是什么样子的呢?如下表
学号 |
学生姓名 |
课程 |
课程编码 |
成绩 |
学分 |
001 |
张三 |
现代文学 |
C01 |
82 |
4 |
002 |
李四 |
古代文学 |
C02 |
55 |
1 |
2NF是在第一范式的基础上建立的,要满足第二范式就要满足一范式。要求数据库表中的每个实例必须可以被唯一区分,还须选取一个能区分每个实体的属性或属性组,作为实体的唯一标识。也就是在第一范式的基础上属性完全依赖于主键。
如上面那个第一范式的例子就不符合第二范式,表中的主键是学号和课程编码,学分这一属性只是部分依赖学号这一主键,所以它不符合第二范式。须拆成两个表即可:如表R1和R2
R1:
学号 |
学生姓名 |
课程编码 |
课程 |
成绩 |
001 |
张三 |
C01 |
现代文学 |
82 |
002 |
李四 |
C02 |
古代文学 |
55 |
R2:
课程编码 |
学分 |
C01 |
4 |
C02 |
4 |
三范式是在第二范式的基础上建立起来的,想要满足第三范式必须满足第二范式。第三范式在第二范式的基础上不可以存在任何非主属性的传递函数依赖函数。
什么是传递函数依赖呢?举个例子,这样比较好理解:比如说我很想接近一个人,偶然间在一个人的资料上发现了他的身份证号,从他的身份证号里,我得到了他的出生年月信息,于是我就在他生日那天,送了礼物,从此两个人的关系就又近了,哈哈……有没有觉得我很聪明?在这里面就有个传递函数依赖:身份证号——>生日——>送礼物——>关系近了。
例子是有了,但是到了关系模式上又是怎么样的呢?先看一下具有非主属性的传递函数依赖的关系模式,学号——>学院代码——>学院名称;学号——>学院代码——>学院地址,所以下表是不符合3NF的。
学号 |
学生姓名 |
学院代码 |
学院名称 |
学院地址 |
001 |
张三 |
D01 |
文学院 |
1号楼 |
002 |
李四 |
D02 |
管理学院 |
2号楼 |
那我们就应该把表拆分成如下两表,这样就不会出现传递函数依赖了。
学号 |
学生姓名 |
学院代码 |
001 |
张三 |
D01 |
002 |
李四 |
D02 |
学院代码 |
学院名称 |
学院地址 |
D01 |
文学院 |
1号楼 |
D02 |
管理学院 |
2号楼 |
BCNF是在3NF的基础上建立起来的,它比2NF和3NF中设计规范要求更强,可以是数据库的冗余度更小。BCNF消除了任何属性对码的传递依赖与部分依赖。这个是很难做到的,所以就不举例了。
总结还是用个表格吧,让这几个模式在对比中再学一遍,有没有觉得很简单啊?
范式 |
要求 |
1NF |
实体中的属性不可以是多值 |
2NF |
在1NF的基础上属性完全依赖于主键,不可以有部分依赖 |
3NF |
在2NF的基础上不可以存在任何非主属性的传递函数依赖函数。 |
BCNF |
在3NF的基础上消除了任何属性对码的传递依赖与部分依赖。 |