函数依赖是关系模式中属性之间的一种逻辑依赖关系。
eg:
在关系模式R中,X和Y是R关系的子集,X的真子集X’,有X’->Y,则称Y对X部分函数依赖。
eg:
在关系模式R中,X,Y,Z是U的子集,若X->Y,Y-/->X,Y->Z,则有Z对X传递函数依赖
eg:
第一范式(1NF):每一列要保持原子特征 列是基本数据项,不能再进行拆分,否则设计成一对多的关系
不满足第一范式就不能称之为关系型数据库
学生表(学号、用户名、性别、年龄,地址)
这里的地址我可以输入很多信息
eg:陕西省西安市未央区xx小区
陕西省咸阳市xx小区
这样是及其不规范的,而且地址包括很多原子信息
拆分改造后:
学生表(学号、用户名、性别、年龄、地址ID)
地址表(地址ID、省、市、区)
第二范式(2NF):每个非主属性都完全函数依赖于R的主关系键
也就是说在第一范式的基础上,消除非主属性对主关系键的部分函数依赖,就可以成为第二范式。
注意:部分函数依赖是多值函数依赖,所以如果主关系键只有一个属性,那么自动就满足了第二范式
以刚才的例子来说:
现在有一个关系模式SCD(sno,cno,Score,sname)
sno:学号 cno:课程号 Score:成绩 sname:姓名
在上面的部分函数依赖中已经分析得出,sname部分函数依赖于sno,所以这个关系模式没有达到第二范式,如何达到呢?
消除非主属性对主关系键的部分函数依赖。
拆分SCD
S(sno,sname) SC(sno,cno,Score)
第三范式(3NF):每个非主属性都不传递函数依赖R的主关系键
也就是说在第二范式的基础上,消除非主属性对主关系键的传递函数依赖,就可以成为第三范式。
还是以刚才的例子来说:
现在有一个关系模式 R(sno,sname,dept,depter)
sno:学号 sname:姓名 dept:院系 depter:院长
通过刚才的分析,非主属性depter传递函数依赖主关系键sno,所以不满足第三范式,这时就要消除depter对sno的传递函数依赖,拆分R
S(sno,sname,dept) D(dept,depter)
BC范式(BCNF):消除主属性或非主属性对主关系键的部分函数依赖和传递函数依赖,就可以达到第三范式。
仔细分析这句话,可以排除很多无关因素,因为要达到BC范式,这时关系肯定已经达到了第三范式:已经消除了非主属性对主关系键的部分函数依赖和传递函数依赖。一般主要考虑的是主属性对主关系键的部分函数依赖。
举一个例子:
关系模式SNO(sno,sid,cno,Score)
sno:学号 sid:身份证号 cno:课程号 Score:成绩
分析该关系模式,很明显这是一个学生选课的关系,sno学号 和 sid身份证号都可以唯一的确定一个学生,但是确定不了选课关系,要想确定一个选课关系,还需要学号cno,也就是说这个关系有两个候选键(sno,cno)和(sid,cno)
主属性:sno,sid,cno 非主属性:Score
分析发现已经满足第三范式,不存在非主属性的部分和传递函数依赖。
关系:
sno<–>sid
(sno,cno)–>Score,sid
(sid,cno)–>Score,cid
这里面就存在了主属性对主关系键的部分函数依赖
要满足BC,可以拆分,消除这种关系
A(sno,sn) B(sno,cno,Score)