通俗易懂理解数据库范式
关系型数据库范式(NF)的概念:符合某种级别的关系模型的集合,表示一个关系内部各个属性之间联系的合理化程度。
很难懂对不对?大体上,范式指的是,一张数据表的级别。
一范式(1NF)是基础级别;大家都要有的。概念是:数据库表每一项都是不可再分的项;用一句简单的话说,就是所有的属性都是单一的,你不能一个格里面写俩属性,也没地儿写啊不是。图解:
姓名 | 学号 | 年龄 | 基本信息 | |
奔波儿灞 | 0101 | 17 | 团员 | 班长 |
霸波尔奔 | 0102 | 18 | 团员 | 学习委员 |
这个(姓名,学号,年龄,基本信息)就不符合基础级别(1NF),基本信息是可以再分的,因为数据表中,一格是不能同时写上多个数据的。
二范式(2NF)是建立在一范式的基础上的。概念是数据表的实例或者属性必须被唯一的区分。同样用简单的话说,就是你不能把所有的信息放一块儿吧。总得根据关键信息把表分开吧。不然查起来多麻烦。就像学生信息表,班长拿了一张学生信息表,里面写的电话QQ微信身份证班级学号,再加点和学校有关的差不多就够了。但是学生的信息太多了,兴趣爱好,性格特长,家庭成员,等等等等信息,放在同一张表是不可能的。图解:
姓名 | 学号 | 班级 | 身份证 | 籍贯 | 出生日期 | 性别 | 家庭电话 | 家庭住址 | 兴趣爱好 | 专业 | 社团 | 民族 | 宿舍 | ... ... |
孙权 | 0101 | 1班 | 0101123 | 吴 | 东汉末年 | 男 | 123 | 东吴 | 十万北伐 | 木材手工 | 东吴 | 汉族 |
1号 |
... ... |
刘备 | 0102 | 2班 | 0102233 | 蜀 | 东汉末年 | 男 | 233 | 巴蜀 | 种菜织席 | 表演 | 巴蜀 | 汉族 | 2号 | ... ... |
曹操 | 0103 | 3班 | 0103155 | 魏 | 东汉末年 | 男 | 1551 | 北魏 | 铜雀台 | 装睡 | 北魏 | 汉族 | 3号 | ... ... |
我们可以看到这张表已经满足一范式了。他的属性都被分得明明白白的。
不同的信息,他们的身份证号码不同,学号也不同。我们就可以说,身份证和学号是这张表的码。
出生日期,籍贯,这之类的信息,主要是由身份证来区分的。而班级信息基本是靠学号区分。这就是说,如果我想查班级信息,我拿到学号就够了,身份证号码对于我想查的班级信息,并没有必要。我们就称这种表存在不完全依赖。去掉这种不完全依赖的办法,就是以学号,身份证号码,将上面的一大张表,拆成两张,一张以学号作码,一张以身份证做码。这样就去掉了不完全依赖,就符合第二范式了。拆开之后,应该是这样:
身份证 | 家庭住址 | 出生日期 | 民族 |
0101123 | 东吴 | 东汉末年 | 汉族 |
0102233 | 巴蜀 | 东汉末年 | 汉族 |
0103155 | 北魏 | 东汉末年 | 汉族 |
学号 | 姓名 | 班级 | 专业 | 专业老师 | 专业成绩 |
0101 | 孙权 | 1班 | 木材手工 | 周瑜 | 100分 |
0102 | 刘备 | 2班 | 表演 | 子龙 | 100分 |
0103 | 曹操 | 3班 | 装睡 | 杨修 | 100分 |
三范式(3NF)是建立在二范式的基础上的。概念是:一个数据表中不能包含已经在别的表中的非关键信息,属性不依赖其他非主属性。就是说,说,一张表中的所有属性,都由它的码直接决定,不能依靠其他的中间属性,如果有这样的中间属性,那就应该拆分成新的表。我们可以这样理解,上面的学生信息表,专业成绩由专业老师给出。依据学号,是无法直接拿到专业成绩的。如果我们需要满足三范式,就必须将专业,专业老师,专业成绩拆分为一个新的表(专业信息表),原来的学生信息表的信息就能够全部由学号直接决定,这样我们就可以说满足了第三范式。新的表应该长这样:
学号 | 姓名 | 班级 | 专业 |
0101 | 孙权 | 1班 | 木材手工 |
0102 | 刘备 | 2班 | 表演 |
0103 | 曹操 | 3班 | 装睡 |
专业 | 老师 |
木材手工 | 周瑜 |
表演 | 子龙 |
装睡 | 杨修 |
这时候你要问了,专业成绩怎么看?专业成绩表,这张表是以(学号,专业)作为码,成绩作为非主属性,那么就应该多一张表:
学号 | 专业 | 成绩 |
0101 | 木材手工 | 100分 |
0102 | 表演 | 100分 |
0103 | 装睡 | 100分 |
这样的数据关系,才符合第三范式。
BC范式(BCNF)被称为是修正版的第三范式,概念是不能存在非主属性对主键子集依赖。这个我要另外举一个例子,假如有一所学校要统计物理、化学、生物等学科的竞赛证书数量,学校设计了这样的一张表
班级 | 班主任 | 竞赛学科 | 证书数目 |
1班 | 刘老师 | 物理 | 10 |
1班 | 刘老师 | 化学 | 15 |
2班 | 王老师 | 生物 | 20 |
2班 | 王老师 | 物理 | 10 |
... ... | ... ... | ... ... | ... ... |
这张表的码是(班级,班主任,竞赛学科),非主属性是证书数目。证书数目由(班级,竞赛学科)决定,也可以说是由(班主任,竞赛学科)决定,因为班级和班主任是可以互相推导的。这张表符合1NF元素不可分。符合2NF,因为证书数目由(班级,竞赛学科)决定,但是(班主任,竞赛学科)也能决定。对于3NF,它也是符合的,因为只有一个非主属性,肯定是由码直接决定的啦。那么BCNF的规范是什么呢?就是不能有主属性的互相推导。就是说,如果存在(班级->班主任)(班主任->班级)这种关系,是不符合BCNF的。如果要符合BCNF那就需要将上面的表进行拆分;成为下面这种情况。
班级 | 竞赛学科 | 证书数目 |
1班 | 物理 | 10 |
1班 | 化学 | 15 |
2班 | 生物 | 20 |
2班 | 物理 | 10 |
... ... | ... ... | ... ... |
班级 | 班主任 |
1班 | 刘老师 |
2班 | 王老师 |
... ... | ... ... |
这样就不存在证书数目对于码的子集依赖,符合BCNF。在实际应用中,BCNF应该是数据冗余度比较低的了,实际上我目前在工作中的数据表都是满足第三范式而已,有的数据关系仅仅是满足第二范式。
如有错误,欢迎读者能够批评指正。感谢阅读,期待您的评论。