关系模式:关系模式相当于一张二维表的框架,在这个框架下填入数据,称为关系模式的一个实例,或者叫关系(R)。
R(A1,A2,A3...Ai):R是关系名,Ai是关系的属性名。一个关系名对应一张表,关系名对应表名,属性对应表中的列名。
在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库
e.g.如下的数据库表是符合第一范式的:
字段1 字段2 字段3 字段4
而这样的数据库表是不符合第一范式的:
字段1 字段2 字段3(字段3.1,字段3.2) 字段4
第二范式(2NF)
第二范式是在第一范式的基础上建立起来的,即满足第二范式必须先满足第一范式(1NF)。
定义:如果关系模式R属于1NF,且每一个非主属性都完全依赖于主码,则称关系R是属于第二范式的,记作R属于2NF。
第二范式(2NF)说明:要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖于主关键字的一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。
e.g.
假定选修课关系表为SelectCourse(学号,姓名,年龄,课程名称,成绩,学分),关键字为组合关键字(学号,课程名称),因为存在如下决定关系:
(学号,课程名称)->(姓名,年龄,成绩,学分)
这个数据库表不满足第二范式,因为存在如下决定关系:
(课程名称)->(学分)
(学号)->(姓名,年龄)
即存在学分和姓名,年龄部分依赖于主关键字。
由于不符合2NF,这个选课关系表会存在如下问题:
(1)数据冗余:
同一门课程会有N个学生选修,“学分”就会重复N-1次;同一个学生选修了M门课程,那姓名和年龄会重复M-1次。
(2)更新异常:
若课程的学分更新,那必须把表中所有的学分值都更新,不然会出现同一课程出现不同的学分。
(3)插入异常:
假设要开设一门新的课程,但是目前还没有学生选修这门课程,由于没有学号导致数据无法录入到数据库中。
(4)删除异常:
假设一批学生已经完成课程的选修,这些选修记录就应该从数据库中删除,但是,同时,课程名称和学分信息也被删除了。很显然,这也会导致插入异常。
所以我们将设计修改了一下,把选课关系表SelectCourse改为如下三个表:
学生:Student(学号,姓名,年龄)
课程:Course(课程名称,学分)
选课关系:SelectCourse(学号,课程名称,成绩)
这样的数据库表是符合第二范式的,消除了数据冗余,更新,插入,删除异常。
注:所有的单关键字的数据库表都符合第二范式,因为不可能存在组合关键字,也就不可能存在非主属性部分依赖于主关键字了。
第三范式
定义:如果关系模式R属于2NF,并且R中的非主属性不传递依赖与R的主码,则称关系R是属于第三范式的。(个人总结,非主属性必须直接依赖于主码,不能存在通过其他非主属性传递依赖于主码)
所谓传递依赖,就是A依赖于B,B依赖于C,则A传递依赖于C。
因此,满足第三范式的数据库表应该不存在如下依赖关系:
关键字段->非关键字段x->非关键字段y
e.g.
假定学生关系表为Student(学号,姓名,年龄,所在学院,学院地点,学院电话),关键字为单一的学号,所以肯定符合第二范式,但是因为存在非关键字学院地点和学院电话依赖于所在学院,即传递依赖于学号,所以此关系表不符合第三范式。同样会导致数据冗余,DDL操作异常等问题。
所以我们可以对其进行修改:
学生:(学号,姓名,年龄,所在学院)
学院:(学院,地点,电话)
这样的数据库表就符合第三范式了。
总结:
a. 规范化目的是使结构更合理,消除存储异常,减少数据冗余,便于插入,删除,更新。
b. 原则:遵从概念单一化“一事一地”原则,即一个关系模式描述一个实体或实体建的一种联系。
c. 方法:将关系模式投影,分解成两个或两个以上的关系模式。
d. 分解后的关系模式集合应当与原关系模式保持等价关系,即通过自然联接可以恢复原关系而不丢失信息,并保持属性间合理的联系。
注意:一个关系模式结合分解可以得到不同关系模式集合,也就是说分解方法不是唯一的。最小冗余的要求必须以分解后的数据库能够表达原来数据库所有信息为前提来实现的。其根本膜表是节省存储空间,避免数据不一致性,提供对关系的操作效率,同事满足应用需求。实际上,并不一定要求全部模式都达到BCNF不可。有时候故意保留部分冗余可能更方便数据查询。尤其对于那些更新频度不高,查询频率极高的数据库系统更是如此。在关系数据库中,除了函数依赖之外还有多值依赖,联接依赖的问题,从而提出了第四范式,第五范式等更高一级的规范化要求。