数据库范式实例
2016-06-15 08:50
260 查看
目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。
基本上就是从所有字段都放在一个表中—>所有字段都不放在一个表中的这样一个过程。
第一范式:每一个字段代表一个属性,不能由重复的属性,重复的字段。
第二范式:主键的出现,属性与主键的依赖关系。
第三范式:传递依赖关系,如,一个学生对应一个系别,一个系别中有多个以系别为中心的属性,这时候如果将系别的信息和学生放在一个表中就会系别相关属性的重复出现。这时候将系别与其属性放在另一个表中,就会防止这种情况。这种对数据表的划分就是所谓的第三范式。
下面以一个学校的学生系统为例分析说明,这几个范式的应用。
数据库表中的字段都是单一属性的,不可再分。这个单一属性由基本类型构成,包括整型、实数、字符型、逻辑型、日期型等。在当前的任何关系数据库管理系统(DBMS)中,傻瓜也不可能做出不符合第一范式的数据库,因为这些DBMS不允许你把数据库表的一列再分成二列或多列。因此,你想在现有的DBMS中设计出不符合第一范式的数据库都是不可能的。
首先我们确定一下要设计的内容包括那些。学号、学生姓名、年龄、性别、课程名称、课程学分、系别、学科成绩,系办地址、系办电话等信息。为了简单我们暂时只考虑这些字段信息。我们对于这些信息,所关心的问题有如下几个方面。
学生有那些基本信息?
学生选了那些课,成绩是什么?
每个课的学分是多少?
学生属于那个系,系的基本信息是什么?
首先我们考虑,把所有这些信息放到一个表中(学号,学生姓名、年龄、性别、课程、课程学分、系别、学科成绩,系办地址、系办电话)下面存在如下的依赖关系。
(学号, 课程名称) → (姓名, 年龄, 成绩, 学分)
问题分析
因此不满足第二范式的要求,会产生如下问题:
数据冗余:同一门课程由n个学生选修,"学分"就重复n-1次;同一个学生选修了m门课程,姓名和年龄就重复了m-1次。
更新异常:
1)若调整了某门课程的学分,数据表中所有行的"学分"值都要更新,否则会出现同一门课程学分不同的情况。
2)假设要开设一门新的课程,暂时还没有人选修。这样,由于还没有"学号"关键字,课程名称和学分也无法记录入数据库。
删除异常 :假设一批学生已经完成课程的选修,这些选修记录就应该从数据库表中删除。但是,与此同时,课程名称和学分信息也被删除了。很显然,这也会导致插入异常。
解决方案
把选课关系表SelectCourse改为如下三个表:
学生:Student(学号,姓名,年龄,性别,系别,系办地址、系办电话);
课程:Course(课程名称,学分);
选课关系:SelectCourse(学号,课程名称,成绩)。
接着看上面的学生表Student(学号,姓名,年龄,性别,系别,系办地址、系办电话),关键字为单一关键字"学号",因为存在如下决定关系:
(学号)→ (姓名,年龄,性别,系别,系办地址、系办电话
但是还存在下面的决定关系:
(学号) → (系别)→(系办地点,系办电话)
即存在非关键字段"系办地点"、"系办电话"对关键字段"学号"的传递函数依赖。
它也会存在数据冗余、更新异常、插入异常和删除异常的情况。(数据的更新,删除异常这里就不分析了,可以参照2.1.1进行分析)
根据第三范式把学生关系表分为如下两个表就可以满足第三范式了:
学生:(学号,姓名,年龄,性别,系别);
系别:(系别,系办地址、系办电话)。
上面的数据库表就是符合I,Ⅱ,Ⅲ范式的,消除了数据冗余、更新异常、插入异常和删除异常。
基本上就是从所有字段都放在一个表中—>所有字段都不放在一个表中的这样一个过程。
第一范式:每一个字段代表一个属性,不能由重复的属性,重复的字段。
第二范式:主键的出现,属性与主键的依赖关系。
第三范式:传递依赖关系,如,一个学生对应一个系别,一个系别中有多个以系别为中心的属性,这时候如果将系别的信息和学生放在一个表中就会系别相关属性的重复出现。这时候将系别与其属性放在另一个表中,就会防止这种情况。这种对数据表的划分就是所谓的第三范式。
下面以一个学校的学生系统为例分析说明,这几个范式的应用。
第一范式(1NF)
数据库表中的字段都是单一属性的,不可再分。这个单一属性由基本类型构成,包括整型、实数、字符型、逻辑型、日期型等。在当前的任何关系数据库管理系统(DBMS)中,傻瓜也不可能做出不符合第一范式的数据库,因为这些DBMS不允许你把数据库表的一列再分成二列或多列。因此,你想在现有的DBMS中设计出不符合第一范式的数据库都是不可能的。首先我们确定一下要设计的内容包括那些。学号、学生姓名、年龄、性别、课程名称、课程学分、系别、学科成绩,系办地址、系办电话等信息。为了简单我们暂时只考虑这些字段信息。我们对于这些信息,所关心的问题有如下几个方面。
学生有那些基本信息?
学生选了那些课,成绩是什么?
每个课的学分是多少?
学生属于那个系,系的基本信息是什么?
第二范式(2NF)
首先我们考虑,把所有这些信息放到一个表中(学号,学生姓名、年龄、性别、课程、课程学分、系别、学科成绩,系办地址、系办电话)下面存在如下的依赖关系。(学号, 课程名称) → (姓名, 年龄, 成绩, 学分)
问题分析
因此不满足第二范式的要求,会产生如下问题:
数据冗余:同一门课程由n个学生选修,"学分"就重复n-1次;同一个学生选修了m门课程,姓名和年龄就重复了m-1次。
更新异常:
1)若调整了某门课程的学分,数据表中所有行的"学分"值都要更新,否则会出现同一门课程学分不同的情况。
2)假设要开设一门新的课程,暂时还没有人选修。这样,由于还没有"学号"关键字,课程名称和学分也无法记录入数据库。
删除异常 :假设一批学生已经完成课程的选修,这些选修记录就应该从数据库表中删除。但是,与此同时,课程名称和学分信息也被删除了。很显然,这也会导致插入异常。
解决方案
把选课关系表SelectCourse改为如下三个表:
学生:Student(学号,姓名,年龄,性别,系别,系办地址、系办电话);
课程:Course(课程名称,学分);
选课关系:SelectCourse(学号,课程名称,成绩)。
第三范式(3NF)
接着看上面的学生表Student(学号,姓名,年龄,性别,系别,系办地址、系办电话),关键字为单一关键字"学号",因为存在如下决定关系:(学号)→ (姓名,年龄,性别,系别,系办地址、系办电话
但是还存在下面的决定关系:
(学号) → (系别)→(系办地点,系办电话)
即存在非关键字段"系办地点"、"系办电话"对关键字段"学号"的传递函数依赖。
它也会存在数据冗余、更新异常、插入异常和删除异常的情况。(数据的更新,删除异常这里就不分析了,可以参照2.1.1进行分析)
根据第三范式把学生关系表分为如下两个表就可以满足第三范式了:
学生:(学号,姓名,年龄,性别,系别);
系别:(系别,系办地址、系办电话)。
上面的数据库表就是符合I,Ⅱ,Ⅲ范式的,消除了数据冗余、更新异常、插入异常和删除异常。
相关文章推荐
- Django中model使用迁移(migrate)部分数据库会遇到的坑
- mysql 5.7.13 winx64安装配置方法图文教程
- 数据库查询3
- 批量修改mysql表、表、数据库的字符校对规则
- 让我震惊的SqlServer 对 ''特殊的处理
- 数据库总结2
- Sql server使用Merge关键字做插入或更新操作
- MySQL字符集的校对规则(collation rule)
- oracle 数据中文出现乱码 ???
- SQLite
- ORA-01034: ORACLE not available ORA-27101: shared memory realm does not exist Linux Error: 2: No suc
- asp.net 连接oracle 数据库-OracleClient使用
- MYSQL数据库导入数据时出现乱码的解决办法
- win2008 R2中安装MySQL出现ODBC连接器安装错误
- Redis3.0 配置文件说明
- SqlServer主键外键添加及判断表是否存在
- mysql 5.7.13 winx64安装配置方法图文教程
- 对mysql数据库的操作
- 关于数据字典的常用SQL文
- 免安装Oracle客户端软件-使用pl/sql配置登陆