范式:符合是一种级别的关系模式的集合,表示一个关系内部各属性之间的联系的合理化程度。
通俗点讲就是一张数据表的表结构所符合的某种设计标准的级别。
目前数据库的范式共有6中,即第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)、第五范式(5NF)。
第二范式是在第一范式的基础上,第三范式是在第二范式的基础上,依次递推。
数据冗余:出现大量的冗余数据。
举例:现有设计学生表(学号,姓名,学院):
学号 | 姓名 | 学院 |
---|---|---|
1 | 张三 | 计算机学院 |
2 | 李四 | 计算机学院 |
3 | 王五 | 计算机学院 |
n | n | 计算机学院 |
在这个表中大量重复了计算机学院,大大消耗了数据库的存储空间,这既是数据冗余。
插入异常:数据由于某种原因无法插入。
假设要开设一门新的课程,暂时还没有人选修。这样,由于还没有"学号"关键字,课程名称和学分也无法记录入数据库。
举例:现设计课程表(学号,课程名称,学分),其中学号为课程表的主键。
当新增一门课程时,由于还没有学生选这门课(主键不存在),那么课程的相关信息也是不能插入的。
更新异常:一个元素进行了修改,所有的与该元素有关的元组都需要修改。
举例:现有学生表(学号,学院名称)
学号 | 学院名称 |
---|---|
1 | 计算机 |
2 | 计算机 |
当计算机学院更名为人工智能学院时,我需要把,学生表中所有的数据都更新一遍。
删除异常:删除一些数据,把不想删的数据也删掉了。
举例:现有学生表(学号,姓名,班级,班主任)
当这个班级的学生毕业了,在删除这个班的学生信息时,同时也把班主任删掉了。
数据表中的每一列数据都是不可分割的。
即一个属性可以继续再分。
第一范式正例:
学生表(学号,姓名,家庭电话,移动电话)
定义:在第一范式的前提上,非主属性完全函数依赖于码。
提示:只有当数据表中,主码有两个或两个以上的属性组合而成时,才会出现不符合第二范式的情况。
第二范式反例:
选课表(学号,课程号,课程名);其中(学号,课程号)为主键
在这张表中
(学号,课程号)-> 课程名
(课程号) -> 课程名
可以看出课程名其实只依赖于课程号,如果把(学号,课程号)设为主键,那么就出现了部分依赖(多此一举)。
解决方法:(把一张表分为两张表)
选课表(学号,课程号)
课程表(课程号,课程名)
定义:在满足第二范式的基础上,没有传递依赖。
传递依赖:A -> B,B -> C,那么就存在A->C,这就是传递依赖。
第三范式反例:
学生表(学号,姓名,系号,系名称)
在这张表中,学号可以决定系号,系号可以决定系名称,那么就有学号可以决定系名称:
解决方法:(建立中间表)
符合3NF要求的数据库设计,基本上解决了数据冗余过大,插入异常,更新异常,删除异常的问题。
BCNF与第三范式的不同之处在于:第三范式中不允许非主属性被另一个非主属性决定,但第三范式允许主属性被非主属性决定;而在BCNF中,任何属性(包括非主属性和主属性)都不能被非主属性所决定。
任何一个BCNF必然满足:
总结:
BCNF:满足3NF,还满足主属性不依赖主属性(两个主属性不相互依赖)
第三范式只判断非主属性是否部分依赖和传递依赖主属性。
BCNF既判断非主属性,又判断主属性是否有部分依赖和传递依赖。
若一个关系达到了第三范式,并且它只有一个候选码,或者它的每个候选码都是单属性(非多个属性组合而成的候选码),则该关系自然达到BCNF。