通俗易懂三大范式
第一范式说的是每个字段不可再分
第二范式说的是不能存在部分依赖(不能由联合主键的部分就可以推出其他字段,必须整个联合主键才能推出其他字段)
第三范式说的是不能存在间接依赖(A(主键)→B,B→C,A→C,就是存在间接依赖),也就是说非主键字段之间不能存在依赖
能被谁推出,就依赖谁 这句话太牛逼太经典了
首先得理清楚四个概念:依赖,完全依赖,部分依赖,间接依赖
1.什么是依赖关系
对于这张表,学生编号+教师编号作为联合主键
由学生编号1001,可以推出学生姓名是张三
由教师编号是001,可以推出教师的姓名是王老师
这种由”一个字段的值可以推出另一个字段的值",我们说这两个字段之间有依赖关系,而且A可以推出B,A->B,则说B依赖于A,能被谁推出,就依赖谁
因为学生编号可以推出学生姓名,所以说学生姓名字段依赖于学生编号字段
教师编号可以推出教师姓名,所以说教师姓名字段依赖于教师编号字段
2.什么是完全依赖关系和部分依赖关系?
联合主键其实是一个集合——(教师学生编号,编号),如果必须学生编号+教师编号(即两个字段的值都必须有)才能推出学生姓名,那我们说学生姓名完全依赖于这个集合(学生编号,教师编号)。但是,这里显然只需要这个集合中的一个子集(仅仅一个学生编号)就可以推出学生姓名了,所以学生姓名这个字段是部分依赖于这个集合(教师学生编号,编号)的。
由此我们可以进行抽象总结:
假如一张表有A,B,C,D,E四个字段,而且主键是(A,B,C),D和E是非主键字段,如果必须A+B+C才能推出D,而(A,B,C)的任何一个子集都无法推出D,就可以说D完全依赖于(A,B,C),如果(A,B,C)的一个子集就可以推出D,则说D部分依赖于(A,B,C)
显然,只有联合主键才会存在完全依赖和部份依赖一说,单一主键没有这么一说。
3.什么是间接依赖?
假设有一个表,里面的字段是学号,姓名,系名,系大楼,
学号可以推出系名,
系名可以推出系大楼,
根据这个关系链可以由学号推出系大楼,就说系大楼字段是间接依赖于学号字段的。
有这样的关系A(主键)→B,B→C,A→C,就是存在间接依赖
但是如果不存在B→C,只有A(主键)→B,A→C就说明不存在间接依赖关系。
也就是说,不存在间接依赖的本质是:非主键之间没有依赖关系,即两个非主键字段之间不存在一个字段可以推出另一个字段的关系!!!
4.当你理解完这四个概念,再看什么是三大范式
1.第一范式
必须规定一个字段为主键,而且每个主键都不能再分
2.第二范式
非主键字段必须完全依赖于主键(一般是联合主键而不是单一主键),不能部分依赖于主键
3.第三范式
不能有依赖传递
5.实例讲解
没有分解前的表:
sno学生编号和Cname课程名字组成联合主键,存在以下依赖关系:
(1) 学生编号Sno可以推出学生姓名Sname和学生所属学院Sdept,Sno -> Sname, Sdept,也就是学生姓名Sname和学生所属的学院Sdept依赖于学生编号Sno
(2)学生所属学院Sdept可以推出院长的名字Mname,Sdept -> Mname
(3)学生编号Sno+课程名字Cname两个联合主键可以推出学生成绩Grade,Sno, Cname-> Grade
所以,学生成绩Grade完全依赖于联合主键,学生姓名Sname,学生学院Sdept,院长姓名Mname部分依赖于联合主键
第二范式要求非主键字段必须完全依赖于主键(一般是联合主键而不是单一主键),不能部分依赖于主键,这里有字段部分依赖主键,所以不满足第二范式、
将一张表拆分成两张表:
表一的主键是学生编号Sno,表二的主键是学生编号Sno和课程姓名Cname组成的联合主键
虽然不再存在部份依赖了,但是表一中存在依赖传递,Sno -> Sdept -> Mname,也就是学生编号无法直接推出院长名字,存在依赖传递违反了第三范式,最后分解成以下两张表:
最后每张表中既不存在部分依赖,也不存在间接依赖