数据库三大范式详解

来源:互联网 发布:psd免费源码社区 编辑:程序博客网 时间:2024/06/06 17:49

第一范式1NF

数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。
如果出现重复的属性,就需要定义一个新的实体,新的实体由重复的属性构成,新的实体和原实体之间是一对多关系。
在任何一个关系型数据库中,第一范式是基本的要求,必须满足。
下面看例子:
这里写图片描述
上面的数据表是不符合第一范式的,因为进货下面又可以再次划分为数量和单价,销售同理。满足第一范式的数据表应设计如下:
这里写图片描述

仅仅满足第一范式的数据库表还会存在很多问题,如数据冗余过大,插入异常,删除异常,修改异常。看下表;
这里写图片描述

存在的问题:
1 每一名学生的学号 姓名 系名 系主任这些数据重复过多,每个系与系主任的数据也重复多次——数据冗余
2 假设学校新开了一个系,但是这个系还没有开始招生,那么现在是无法将系主任和系名的数据添加到上述的表中——插入异常
3 假设将某个系中的所有学生的相关记录全部删除,那么系和系主任的数据也随之消失了,但是学生记录不存在,并不意味着这个系就没有了——删除异常
4 假设小明转到哲学系,那么为了保证数据库的一致性,需要修改三条记录中系与系主人的数据——修改异常
因此需要提高设计标准,使其符合更高一级的范式2NF,即“规范化”。

    -

第二范式2NF

第二范式是在第一范式基础上建立起来的,即必须先满足第一范式。第二范式要求数据库表中的每个实例或者行必须可以被唯一的区分。为实现区分,通常需要为每个表加上一个列,以存储各个实例的唯一标识。这个唯一的属性列称为主键字或主键 主码。
第二范式要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体和原实体之间是一对多的关系。简而言之,就是非主属性非部分依赖于主关键字。
如下表:
学生 课程 教师 教师职称 教材 教室 上课时间
李四 Spring 张老师 java讲师 《Spring深入浅出》 301 08:00
张三 Struts 杨老师 java讲师 《Struts in Action》 302 13:30
这里通过(学生 课程)可以确定一条记录。故将其作为联合主键,但是教材并不完全依赖于(学生 课程),只拿出部分课程就可以确定教材。这是部分依赖。
正确的表应设计如下:
选课表
学生 课程 教师 教师职称 教室 上课时间
李四 Spring 张老师 java讲师 301 08:00
张三 Struts 杨老师 java讲师 302 13:30
课程包:
课程 教材
Spring 《Spring深入浅出》
Struts 《Struts in Action》
第二范式消除了部分依赖,减少了插入异常 删除异常和修改异常。

如果继续以第一范式中那张表为例,(学号 课名)作为主键才能唯一标识分数,但是其他的属性如姓名 系名和系主任只需要学号就可以唯一确定了,这也是部分依赖了。
将表修改如下:
这里写图片描述
是否还存在之前的问题?
1 小明转到法律系,只需要修改一次对应的系的值即可。
2 姓名 系名 系主任没有重复那么多次,数据冗余减少了。
3 删除某个系中学生记录,信息仍然全部丢失。
4 插入一个尚无学生的新系信息,仍然存在插入异常。

第三范式3NF

满足第三范式必须先满足第二范式。第三范式要求一个数据表中不包含已在其他表中包含的非主关键字信息。例如一个部门信息表,每个部门有个部门编号,部门名称等,那么在员工信息表中列出部门编号后,就不能再将部门名称等与部门相关的信息再加入到员工信息表中。如果不存在部门信息表,那根据第三范式也应该构建他,否则就会出现大量的冗余。简而言之,第三范式就是属性不依赖于其他非主属性。(消除传递依赖,消除冗余)。

仍以上述表为例,对于学生表,系名决定了系主任,存在了非主属性系主任对学号的传递函数依赖,不符合3NF。
故对表进行进一步分解:
选课(学号,课名,分数)
学生(学号,姓名,系名)
系(系名,系主任)
这里写图片描述
上述的问题也都得到了解决。
由此可见,3NF基本上解决了数据冗余过大,插入异常,修改异常,删除异常的问题。

总结

  1NF就是原子性,字段不可再分割  2NF就是完全依赖,非主属性完全依赖于主属性,不存在部分依赖  3NF就是非主属性中没有传递依赖。每列中都与主键有直接关系。
0 0
原创粉丝点击