范式来自于英文Normal form,简称NF。要想设计一个好的关系,必须使得关系满足一定的约束条件,此约束已经形成了规范,分成几个等级,一级比一级要求的严格。满足这些规范的数据库是简洁的、结构清晰的。同时不会发生插入、删除、更新操作异常。
第一范式:是指在关系模型中,对于添加的一个规范要求,所有的域应该都是原子性的。即数据库中的每一列都是不可分割的原子数据项,而不能是集合、数组,记录等原子数据项。即实体中的某个属性有多个值时,必须拆分为不同的属性。在符合第一范式(1NF)表中的每个域值只能是实体的一个属性或者属性的一部分。简而言之,第一范式就是无重复的域。
例如:考虑这样一个表:【联系人】(姓名,性别,电话)
如果在实际场景中,一个联系人有家庭电话和公司电话,那么这种表结构设计就没有达到 1NF。要符合 1NF 我们只需把列(电话)拆分,即:【联系人】(姓名,性别,家庭电话,公司电话)。1NF 很好辨别,但是 2NF 和 3NF 就容易搞混淆。
第二范式:
2NF要求的是对记录的唯一性,要求记录有唯一标识,即实体的唯一性,即不存在部分依赖。没有包含主键的列必须完全依赖于主键,而不能只依赖于主键的一部分。
例如:表:学号、课程号、姓名、学分;
这个表明显说明了两个事务:学生信息, 课程信息;由于非主键字段必须依赖主键,这里学分依赖课程号,姓名依赖与学号,所以不符合二范式。
可能出现的问题:
数据冗余:每条记录都含有相同信息
删除异常:删除所有学生成绩,就把课程信息全删除了;
插入异常:学生未选课,无法记录进数据库;
更新异常:调整课程学分,所有行都调整。
正确做法:
学生:Student(学号, 姓名);
课程:Course(课程号, 学分);
选课关系:StudentCourse(学号, 课程号, 成绩)。
第三范式:
在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)。即不能存在:
非主键列A依赖于非主键列B,非主键列B依赖于主键的情况。
考虑一个订单表【Order】(OrderID,OrderDate,CustomerID,CustomerName,CustomerAddr,CustomerCity)主键是(OrderID)。其中 OrderDate,CustomerID,CustomerName,CustomerAddr,CustomerCity 等非主键列都完全依赖于主键(OrderID),所以符合 2NF。不过问题是 CustomerName,CustomerAddr,CustomerCity 直接依赖的是 CustomerID(非主键列),而不是直接依赖于主键,它是通过传递才依赖于主键,所以不符合 3NF。
通过拆分【Order】为【Order】(OrderID,OrderDate,CustomerID)和【Customer】(CustomerID,CustomerName,CustomerAddr,CustomerCity)从而达到 3NF。
第二范式(2NF)和第三范式(3NF)的概念很容易混淆,区分它们的关键点在于,2NF:非主键列是否完全依赖于主键,还是依赖于主键的一部分;3NF:非主键列是直接依赖于主键,还是直接依赖于非主键列。
网友评论