关于数据库范式

     设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小。

目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。满足最低要求的范式是第一范式(1NF)。在第一范式的基础上进一步满足更多规范要求的称为第二范式(2NF),其余范式以次类推。一般说来,数据库只需满足第三范式(3NF)就行了。

但是实际项目开发过程中,随着业务的逐渐庞大,关系型表的之间的关系变得交替复杂,为了提高查询的效率,不得不进行字段冗余操作来进行单表操作;

关于第一范式:(列不可再分)

      我们目前说的和用的数据库都是关系数据库,而关系数据库中是不可能设计一个列能够包含两个不同类型的属性的;但大千世界,无奇不有,除了关系数据库,还有其它的数据库,例如面向对象数据库、XML数据库,这种数据库就可以设计一个属性再包含多个子属,所以1NF在关系数据库中是天然满足的,而在其它类型数据库就不一定了。

第二范式:(不存在属于部分主键的属性)

例如:成绩表Score主键是StudentID和CourseID,另外还有两个属性:一个是成绩Grade,一个是StudentName。这里的Grade就是完全由两个主键决定的(标准术语叫做“完全依赖”),而StudentName就只是StudentID的属性(标准术语叫做“部分依赖”),因此这个设计就不符合2NF。

可能有人会问:那我就把StudentID作为主键可不可以?当然是可以的,但这样一来CourseID就又不符合2NF了,因为CourseID不是StudentID的属性。

说了半天了,都是说我们要遵守范式,但是不遵守范式究竟有什么问题呢?

简单的说就是两个问题:冗余(存储、操作)、异常(插不进、删多了)

(1)冗余

一个学生选了很多课,这样StudentName就要重复很多次,因为重复很多次,所以哪天学生改名了,所有的StudentName记录都要更新。

(2)异常

插不进:刚来一个学生,还没有选课(假设所有的课都要选),那么他的StudentName就没有地方记录

删多了:假如学生毕业的,所有的课都学完了,那么所有的记录都删除,这样学生的名字最后也没有地方记录了。

第三范式:

属性不递归依赖于主键

什么叫递归依赖呢?简单的就是"A → B → C",那么C就是递归依赖(所谓依赖,简单的讲就是“有关系”了)于A了。

什么叫递归依赖呢?简单的就是"A → B → C",那么C就是递归依赖(所谓依赖,简单的讲就是“有关系”了)于A了。

注意:在数据库中,存在这样的关系要求A是主键、B和C不是主键。

下面还是给一个简单的例子:

假定学生关系表为Student(学号, 姓名, 年龄, 所在学院, 学院地点, 学院电话),关键字为单一关键字"学号",因为存在如下决定关系:

(学号) → (姓名, 年龄, 所在学院, 学院地点, 学院电话)

  这个数据库是符合2NF的,因为每个学生的这些信息都和学生本人是有关系的,也就是说由学号来决定,但是不符合3NF,因为存在如下关系:

(学号) → (所在学院) → (学院地点, 学院电话)

  即存在非关键字段"学院地点"、"学院电话"对关键字段"学号"的递归依赖。

  它也会存在数据冗余、更新异常、插入异常和删除异常的情况,大家可以根据2NF样例中的分析方法分析。

 

 

 

 

原文地址:https://www.cnblogs.com/xu-xiang/p/5866810.html