范式是关系型数据库规范程度的级别划分,下面来说说数据库的三大范式。
首先弄清几个概念:
候选码:候选码是可以区别表中一行数据的属性或属性的集合。比如学生表student(id,name,age,sex),其中id可以作为候选码。id和name组合也可以区别表中一行数据,此时id可以称为码,id和name的组合也是码。但是它们不是候选码,因为去掉name,id也可以表示一行数据。而候选码可以说是不可再分的。定义:候选码是可以表示一行数据的最少属性集合。另外,一个表候选码可能有多个,至于选择哪一个作为主码都可以。
主属性:如果一个属性存在于所有的候选码之中,它就称之为主属性。
第一范式(1NF)
数据库表的每一列都是不可再分的原子数据项。
第一范式比较简单,就不必赘述了。
第二范式(2NF)
要弄懂第二范式需要看几个概念,先是几个基础的不重要的,不过对于后面理解还是不得不看:
函数依赖:一张表中,如果给定A属性(属性组)的值,一定能确定属性B的值,记作A->B,这就是函数依赖。
完全函数依赖:如果只有A才能确定B,C不可以,那就是完全函数依赖。
重头戏来了:
部分函数依赖:如果A属性组的部分属性就能确定B属性,如(学号,课名)->姓名,只需学号即可,这就是部分函数依赖。
传递函数依赖:如果A->B,B->C,而A不能直接确定C,那么就是C传递函数依赖A。比如学号->系名,系名->系主任,这就是传递函数依赖。
第二范式解决的就是部分函数依赖的问题。
第二范式要求,消除非主属性对主属性的部分函数依赖。
举例:
主属性:学号,课名
非主属性:姓名,系名,系主任,分数
当前表为:(学号,姓名,系名,系主任,课名,分数)
而只需要学号就可以确定姓名和系名,所以这个表存在部分函数依赖,需要分解。
比如分解为:
选课(学号,课名,分数)
学生(学号,姓名,系名,系主任)
第三范式(3NF)
第三范式要求,消除非主属性对主属性的传递函数依赖。
例子不变。
主属性:学号,课名
非主属性:姓名,系名,系主任,分数
当前已经分了表:
选课(学号,课名,分数)
学生(学号,姓名,系名,系主任)
在学生表中,存在非主属性系主任对主属性学号的传递函数依赖,因为存在学号->系名,系名->系主任。所以继续分解:
选课(学号,课名,分数)
学生(学号,姓名,系名)
系(系名,系主任)
总结:数据范式是为了解决数据表数据冗余,数据插入、删除、更新异常的问题。但是效率不一定提高。因为表越多,就需要多次连接查询。
参考: 最简单的数据库“范式”教程