数据库三范式
数据库三范式的目标: 1.减少数据冗余 2.消除异常(插入、删除、更新) 3. 让数据组织的更加和谐 第一范式(1NF):无重复的列 所谓第一范式(1NF)是指数据库库表的每一列都是不可分割的基本数据项。例如一个实体,实体的一个属性不能有多个或不能有重复的
数据库三范式的目标:
1.减少数据冗余
2.消除异常(插入、删除、更新)
3. 让数据组织的更加和谐
第一范式(1NF):无重复的列
所谓第一范式(1NF)是指数据库库表的每一列都是不可分割的基本数据项。例如一个实体,实体的一个属性不能有多个值或不能有重复的属性。举例:
说明:这个表中的属性值“分'了。“电话”这个属性里对于“小明:属性值分成了了两个。
说明:“电话”这个属性里对于“小明”,属性值分成了了两个。
以上这两种情况都不满足第一范式。针对上述情况可以是这样的表:
第二范式(2NF):属性完全依赖于主键(消除部分子函数依赖)
第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式必须先满足第一范式。第二范式要求数据库表中的每个*或行必须可以被唯一的区分。为实现区分,通常需要为表加上一个列,一存储各个实例的唯一标识。
第二范式要求实体的属性完全依赖主关键字。不能存在仅依赖主关键字一部分的属性。如果存在,这个属性和主关键字的这一部分应该分离出来形成一个新的实体。
举例:
一个学生上一门课,一定在特定某个教室。所以有(学生,课程)->教室
一个学生上一门课,一定是特定某个老师教。所以有(学生,课程)->老师
一个学生上一门课,一定是特定某个教材。所以有(学生,课程)->教材
然而,一个课程,一定指定了某个教材,(学生,课程)作为主键,课程却决定了教材,这就叫做不完全依赖,或者说部分依赖。出现这样的情况,就不满足第二范式!因为:
1、校长要新增加一门课程叫“微积分”,教材是《大学数学》,怎么办?学生还没选课,而学生又是主属性,主属性不能空,课程怎么记录呢,教材记到哪呢? …… 郁闷了吧?(插入异常)
2、下学期没学生学一年级语文(上)了,学一年级语文(下)去了,那么表中将不存在一年级语文(上),也就没了《小学语文1》。这时候,校长问:一年级语 文(上)用的什么教材啊?……郁闷了吧?(删除异常)
3、校长说:一年级语文(上)换教材,换成《大学语文》。有10000个学生选了这门课,改动好大啊!改累死了……郁闷了吧?(修改/更新异常)
那应该怎么解决呢?投影分解,将一个表分解成两个或若干个表:
第三范式(3NF):属性不依赖于其它非主属性(消除传递依赖)
满足第三范式必须先满足第二范式。第三范式要求一个数据库一个数据库表中不包含已在其它表中已包含的肥猪关键字信息。例如,存在一个部门信息表,其中每个部门有部门编号(dept_id)、部门名称、部门简介等信息。那么在的员工信息表中列出部门编号后就不能再将部门名称、部门简介等与部门有关的信息再加入员工信息表中。如果不存在部门信息表,则根据第三范式(3NF)也应该构建它,否则就会有大量的数据冗余。简而言之,第三范式就是属性不依赖于其它非主属性。举例:
一个老师一定能确定一个老师职称。(学生,课程)->老师->职称。
问题:
1、 老师升级了,变教授了,要改数据库,表中有N条,改了N次……(修改异常)
2、 没人选这个老师的课了,老师的职称也没了记录……(删除异常)
3、 新来一个老师,还没分配教什么课,他的职称记到哪?……(插入异常)
小结:数据库不仅仅只有三范式,还有很多范式,范式的等级越高,涉及的表越多。
表多带来的问题:
1.查询时需要连接多个表,增加了查询的复杂度。
2.查询时需要连接多个表,降低了数据库查询的性能。
所以,数据冗余所造成的问题并不是使用数据库范式的必要条件。
但是,第三范式在很大程度上减少了数据冗余,并且减少造成插入异常,更新异常,和删除异常。所以应用到第三范式就已经足够了。