牛文颖 纪宁 大连科技学院
设计出一个合理实用的数据库系统是目前应用领域一个非常重要的课题,而范式分析理论正是数据库设计的一个理论指导,它可以判断设计出的数据库是否是一个好的数据库模式。本文深入浅出地讨论范式理论,以及如何将一个不好的关系模式转换成好的关系模式,同时举出实例分析研究。
任何一个关系模式都应该满足第一范式。第一范式是指关系中的所有属性都是不可再分的数据项[1]。比如下表对属性电话进行了分解,使得该关系不能成为第一范式。
姓名 电话年龄手机 座机大宝 13612345678 021-9876543 22
又如关系模式:单位(单位号,员工号,单位地址,单位电话),一个单位有多个员工,所以员工号有多个值,也使得该关系模式不能成为第一范式。综上两个实例满足第一范式的关系,其属性和属性值都不能再分。
第一范式存在的问题:
对关系模式选课(学号,姓名,性别,出生日期,系号,系名,系地址,课程号,课程名,学分,成绩)进行范式分析。
数据插入异常:关系模型选课满足第一范式。主键是(学号,课程号)。现有需求如下:一个新生报道,还没有选修课程。该新生信息(3,王芳,女,1990-3-3),是否能插入到选课关系中。根据实体完整性约束,主键的每个属性都不能为null的原则。该新生没有选课,不能插入到选课关系中,所以对于第一范式存在插入异常。
数据删除异常:如果某个学生只选修了一门课,由于某种原因,这个学生不选课了,因此要删除该学生的选课记录。这次删除意味着学生的信息也不复存在了。这种情况称为删除异常。
数据修改异常:如果某个学生选课信息发生变化,比如1号“莉莉”由D1改为D2,不仅要修改课程号,同时还要修改课程名及学分。这样使修改变得复杂,容易产生数据不一致。
对上述第一范式产生的问题,实质是把学生实体信息和课程实体信息合在了一起,失去了各自实体数据操作的独立性,对其中一个实体操作势必影响另一个实体。从范式理论上称这种关系为部分函数依赖。下面具体分析第一范式的函数依赖关系:提炼出所有的非主属性和主键的关系。在上例中:非主属性“姓名”、“性别”、“出生日期”,“系号”,“系名”,“系地址”属性只与主键中的学号有关,所以它们部分依赖于主键;非主属性“课程名”、“学分”属性只与主键中的课程号有关,所以它们部分依赖于主键;而非主属性“成绩”即与学号有关,又与课程号有关,所以说成绩完全依赖于主键。
解决第一范式的问题,就是在上述分析依赖关系基础上对关系进行分解。消除部分函数依赖。使其转换为第二范式。
第二范式一定是第一范式,并且不存在非主属性部分函数依赖于主键。
将上例进一步转换为第二范式,将部分函数依赖关系中的主属性和非主属性从关系中提取出来,单独构成一个关系模式:学生(学号,姓名,性别,出生日期,系号,系名,系地址);课程(课程号,课程名,学分);将关系模式中余下的属性,加上主关键字,构成另一个关系。选课(学号,课程号,成绩)。
分解之后解决了第一范式提到的数据操作异常。可以向学生关系中插入没有选课的学生信息,可以在选课关系中删除学生的选课信息,可以在选课表里修改学生的选课信息。
插入异常:例如学生关系模式中:学生(学号,姓名,性别,出生日期,系号,系名,系地址)如果新开了一个系,该系还没有学生,那么该系的信息是不能插入到学生关系中的,因为做为主键的学生不能为空。
删除异常:如果某些学生退学,要删除学生的记录,就会连带删除系的信息,产生删除异常。
修改异常:因为多个学生可以在同一个系,系的其他信息也会重复出现,如果系的电话发生变化,就需要多次修改,容易产生数据不一致。
下面具体分析第二范式的函数依赖关系:在上例中:非主属性“系名”,“系电话”,“系地址”直接依赖于“系号”,而“系号”直接依赖于主键“学号”。所以说非主属性“系名”,“系电话”,“系地址”传递依赖于主键“学号”。
解决第二范式的问题,就是在上述分析依赖关系基础上对关系进行分解。消除传递函数依赖。使其转换为第三范式。
第三范式一定是第二范式,并且不存在非主属性传递函数依赖于主键。
将上例进一步转换为第三范式,将起传递作用的非主属性和直接传递依赖的非主属性构成一个新关系模式:系(系号,系名,系地址),该关系中主键为系号。将关系模式中余下的属性,加上新表中的主键,构成另一个关系:学生(学号,姓名,性别,出生日期,系号),该关系中主键为学号,外键为系号。最终将学生关系模式转换为以下两个关系模式:
系(系号,系名,系地址)
学生(学号,姓名,性别,出生日期,系号)。
分解之后解决了第二范式提到的数据操作异常。
[1]邓丽,数据库简明教程[M],东软电子出版社,2012(105)