范式
范式从本质上讲是一种理论体系、理论框架。在该体系框架之内的该范式的理论、法则、定律都被人们普遍接受。
范式是一种人们普遍接受的规律,定律。
数据库设计三范式
按照这三个范式设计的目的是为了使表不产生冗余。
第一范式(1NF)
表中所有字段必须是原子的,不能是任何集合(数组,表,树,图)。
第二范式(2NF)
第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。
第二范式(2NF)要求数据库表中的每个实例或记录必须可以被唯一地区分。选取一个能区分每个实体的属性或属性组,作为实体的唯一标识。例如在员工表中的身份证号码即可实现每个一员工的区分,该身份证号码即为候选键,任何一个候选键都可以被选作主键。在找不到候选键时,可额外增加属性以实现区分,如果在员工关系中,没有对其身份证号进行存储,而姓名可能会在数据库运行的某个时间重复,无法区分出实体时,设计辟如ID等不重复的编号以实现区分,被添加的编号或ID选作主键。(该主键的添加是在ER设计时添加,不是建库时随意添加)
也就是说要求选择主键,如果字段中没有作为主键的条件,那么就自定义一个自然主键。
第二范式(2NF)要求实体的属性完全依赖于主关键字。不能部分依赖于主键。
部分函数依赖:设X,Y是关系R的两个属性集合,存在X→Y,若X’是X的真子集,存在X’→Y,则称Y部分函数依赖于X。
举个例子:通过AB能得出C,通过A也能得出C,通过B也能得出C,那么说C部分依赖于AB。完全函数依赖:设X,Y是关系R的两个属性集合,X’是X的真子集,存在X→Y,但对每一个X’都有X’!→Y,则称Y完全函数依赖于X。
举个例子:通过AB能得出C,但是AB单独得不出C,那么说C完全依赖于AB.
// 学生部分依赖于(学生编号(PK) 教师编号(PK) )
学生编号(PK) 教师编号(PK) 学生姓名 教师姓名
1001 001 张三 王老师
1002 002 李四 赵老师
1003 001 王五 王老师
1001 002 张三 赵老师
如果出现部分依赖需要拆分。部分依赖大多数出现于多字段组合为主键。
t_student学生表
sno(pk) sname
---------------------
1 张三
2 李四
3 王五
t_teacher 讲师表
tno(pk) tname
----------------------
1 王老师
2 张老师
3 李老师
t_student_teacher_relation 学生讲师关系表
id(pk) sno(fk) tno(fk)
-------------------------------------------
1 1 3
2 1 1
3 2 2
4 2 3
5 3 1
6 3 3
第三范式(3NF)
在2NF基础上,数据表中如果不存在非关键字段对任一候选关键字段的传递函数依赖则符合第三范式。简而言之,第三范式就是属性不依赖于其它非主属性。(在2NF基础上消除传递依赖)
传递函数依赖:设X,Y,Z是关系R中互不相同的属性集合,存在X→Y(Y !→X),Y→Z,则称Z传递函数依赖于X。
举个例子:通过A得到B,通过B得到C,但是C得不到B,B得不到A,那么成C传递依赖于A
// 学生编号能得到班级编号,班级编号能得到班级名称,但是班级名称得不到班级编号,班级编号得不到学生编号
学生编号(PK) 学生姓名 班级编号 班级名称
1001 张三 01 一年一班
1002 李四 02 一年二班
1003 王五 03 一年三班
1004 六 03 一年三班
如果出现传递依赖需要拆分,解决方法就是将依赖于其它非主键的字段拆开,将依赖的字段作为外键。
班级t_class
cno(pk) cname
--------------------------
1 班级1
2 班级2
学生t_student
sno(pk) sname classno(fk)
--------------------------------------------
101 张1 1
102 张2 2
103 张3 2
104 张4 1
105 张5 2