数据库的三范式

与世无争的帅哥 提交于 2020-03-10 15:08:18

范式:符合某一种级别的关系模式的集合,表示一个关系内部各属性之间的联系的合理化程度。

简单来说可以把它粗略的理解为一张数据表的表结构所符合的某种设计标准的级别。就像英语46级,相对代表了英语水平的高低。

满足这些规范的数据库是简洁的,结构明晰的,同时,不会发生增删改操作异常。

数据库范式分为 1NF 2NF 3NF BCNF 4NF 5NF一般我们在设计数据库结构的时候最多只要满足到BCNF就可以了,符合高一级的范式必须符合第一级的范式。

一般设计数据库表的时候符合第三范式就很不错了。

1NF的定义:符合1NF的关系中的每个属性都不可以再分。

在使用数据库管理系统的时候比如mysql,SqlServer等创建的数据表都满足1NF,如果不满足这个范式,是不能创建成功数据表的。属性不可再分割的意思是每一个字段都是最小的,不包含其他字段。不重复,原子性。

例如:字段:姓名 不包含其他字段:年龄。注意:这里说的是字段而不是字段的值!

下面是一个学生表!

这种就是错误的,性别不能包含班级,科目,老师

下面这种才是正确的1NF

1NF存在的问题:

数据冗余,插入异常,删除异常,修改异常的问题。

数据冗余:张三的很多信息都要重复很多次

插入异常:如果要新建一个班级,并且有班级主任。但是因为还没有学生开始学习,所以主键(id就是学号)是空的,肯定是不能插入的。

删除异常:如果要把某个班下面的学生都清空,那么这个老师也就不存在了。就是把主键id姓名年龄性别科目删掉,只剩下班级和老师,这个数据也是非法的不能这样操作。

修改异常:如果需要把学生进行老师交换,就需要把数据里面的班级和老师都修改才可以。就是张三要去二班需要更改班级和老师还有科目(每个班科目不一样)才可以。

 

所以有了下面的2NF(二范式)

2NF:在1NF基础上,消除了非主属性对于码的部分函数依赖。

码:一个表中,可以唯一决定一个元组的属性”集合”。假设K为表中的某个属性,如果可以在确定K的情况下,这个表里面的其他属性都可以确定,那么K就叫做候选码,也叫码。比如通过ID可以获得姓名,年龄,性别,但不可以确定班级,科目,老师。老师可以获取班级。

id--姓名,性别,年龄

老师--班级

(id,老师)这个属性组就叫做码。

码不一定是主键,但是主键一定是码。码可以确定一行数据,比如常见的user表根据用户的身份证号也可以确定这条数据但是身份证号并不是主键ID。身份证号也可以叫做码。

非主属性:非主属性就是对于主属性来说的,上面说到的码就是主属性,比如id和课名。不是主属性的就是非主属性包括姓名,年龄,性别,班级,老师。

函数依赖: 函数 y=f(x) 代表给定一个x的值可以确定y的值。在数据表中,在属性x确定情况下必定能确定Y的值,那就说Y函数依赖于X写作X--Y。比如:在表中给定一个学号,必定能得到一个唯一的姓名。那就是说姓名依赖于学号,写作:学号--姓名

完全函数依赖:在一张表中,如X-Y,且对于X的任何一个真子集(假如属性组X包含超过一个属性的话),X-Y不成立,那么我们称Y对于X完全函数依赖,记做XF-Y。比如:(班级,老师)-- 学生,班级和老师都是X的真子集,班级是一个真子集,老师是一个真子集,但是如果只有班级,或者只有老师,是不能的到一个唯一学生的。也就是说需要两个值确定另外一个值,不然就不能叫完全函数依赖。满足完全函数依赖要求,所以    所以Y完全函数依赖于X。

部分函数依赖:如果Y函数依赖于X,但是Y不完全函数依赖于X,那就叫做部分函数依赖。这个例子再加一条 [2 李四 22 女 数学 二班]的数据。比如:(学号,课名)-- 姓名。由学号可以得到唯一的姓名,但是由课命不能得到唯一的姓名。所以姓名不完全依赖于id和课名。所以称为Y部分函数依赖X。

判断是否符合2NF,就是看数据表中是否存在非主属性对于码的部分函数依赖。若存在,则数据表最高只符合1NF要求,若不存在,则符合2NF的要求。

步骤如下:

1.找出数据表中所有的码。

2.根据第一步所的到的码,找出主属性。id和课名。

3.数据表中,除去所有的主属性,剩下的都是非主属性了。姓名,班级,年龄,性别,教师。

4.查看是否存在非主属性属性对于码的部分函数依赖。上面的表就不符合2NF的范式标准,姓名可以通过课命和id两个数据定位,所以要符合2NF就要进行表拆分。

符合2NF的表如下:

先找码,表里面的码就是id和课名,分数是非主属性。只有课名和id一起用,此案能确定分数。分数完全依赖于课命和id的组合,所以是不存在部分依赖的。分数不可以通过id和课命单独来确定的。所以这个是符合2NF的。

第一个表里面的码只有ID一个,非主属性就是姓名,班主任,班级,他们完全依赖主属性。这个是符合2NF要求的。

 

2NF解决了,数据冗余。

插入异常,以上面表为例新建一个班级没有学生,id还是空的肯定也不行。

删除异常,删除某个班级的学生信息,id和姓名。这个班级也就不存在了,肯定也不行。

修改异常,学生姓名进行更换还是需要修改班级和老师。

 

数据库第三范式

这样就出现3NF 就是基于2NF的基础消除了非主属性对于码的传递函数依赖,也就是说,如果非主属性对于码的传递函数依赖,则不符合3NF的要求。

传递函数依赖:Y依赖于X,Z又依赖于Y,那就是说Z依赖与X。比如班级名依赖于学号,班主任又依赖于班名,那么班主任传递依赖于学号。不满足3NF。

第一个表不存在传递函数依赖,分数需要ID和课名来确定,第二个表通过ID确定姓名和班级。最后一个也不存在传递函数依赖。

解决问题:插入异常,原来新建立一个班级是有异常的,现在没有问题,现在可单独插入班级。删除异常,把某个班级下面的学生清空也是没有问题的。

区分:

第一范式:属性不可再拆分

第二范式:消除了非主属性对于码的部分函数依赖

第三范式:消除传递函数依赖

 

实战经验:如果严格执行三范式那么会对查询造成一定的麻烦,所以在真正工作的时候我们是允许进行一些数据冗余的。一范式一定要符合,二范式尽量符合,3范式看具体情况。这个只是一个规范不是一个死的东西,还是看需求是否需要三范式。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!