数据库设计(三范式,冗余字段,逆范式)
2015-07-31 14:17
274 查看
数据库设计(三范式,冗余字段,逆范式)
在设计数据库的时候,应该注意一下什么呢?首先来看一张表。学生成绩表
姓名 | 性别 | java成绩 | c成绩 | 班级 |
张三 | 男 | 90 | 80 | 一班 |
李四 | 女 | 80 | 90 | 一班 |
杨过 | 男 | 90 | 80 | 一班 |
作为初学者的我看到这章表,我的回答是不会出问题,其实从现实生活中来讲,这的确没什么问题的,记得念中学的时候,每次考完试,心里都很着急,急什么呢?当然是成绩,想想那个时候老师又是怎样把你的成绩信息给列出来的呢?是不是以这样的方式,每个班,甚至整个学校的学生成绩都是使用一张表来列出来的,而我们每个人的成绩利用该表中的一行数据来表示的,其中包括一个学生的学号,姓名,班级,成绩以及排名等等。而这里我们只是专业化成了数据库,一个班级的学生成绩变成了数据库中的一张表,而每个学生的成绩变成了表中的一条记录而已,所以认为没什么问题。但是对数据库的设计来讲,概念就不一样了,这样设计就会很容易出现很多问题。会出现一下什么问题呢。比如像增加异常,删除异常,更新异常等等,下面是几个例子。
eg1:在增加数据的时候,可能发生错误。这叫增加异常
姓名 | 性别 | java成绩 | C成绩 | 班级 |
张三 | 男 | 90 | 80 | 一班 |
李四 | 女 | 80 | 90 | 一班 |
杨过 | 男 | 90 | 80 | 一班 |
小龙女 | 女 | 100 | 70 | 1班 |
eg2:在删除数据时,可能会删除相关的其它数据,这叫删除异常
这句话怎么理解呢?同样,看上面eg1的表,如果我们现在要指定删除班级为“一班”的班级怎么办?这个时候我们使用delete 学生成绩表 where 班级='一班' 的话,就删除了班级='一班'的这些记录,这个时候,不是也给我们带来了不必要的后果吗?这就是删除异常。
eg3:在更新数据的时候,可能会有数据没有更新到。这叫更新异常。
姓名 | 性别 | java成绩 | C成绩 | 班级 |
张三 | 男 | 90 | 80 | 1班 |
李四 | 女 | 80 | 90 | 1班 |
杨过 | 男 | 90 | 80 | 一班 |
1.看上面的表,把他们的数据全部耦合到一起了。
2.因为我这样耦合的设计,导致产生了许多重复的数据,比如班级列,我就添加了三条一模一样的,也就是一班。解决方法:根据实体和关系,我们可以把他们保存在不同的表中,然后可以利用一个外键,来指向我们所需要的数据。据上面例子,我们可以建立两张表:
表1:
班级 | 班级编号 |
一班 | 001 |
二班 | 002 |
学号 | 姓名 | 班级编号 |
0103 | 张三 | 001 |
0104 | 李四 | 001 |
0201 | 杨过 | 002 |
0202 | 小龙女 | 002 |
forms,意思是规范化表。也表示将表进行分类处理,这个过程就叫做规范化。简单理解,规范化表的过程,就是将数据进行分类的过程。下面说说这三个范式。
1 第一范式(1NF)
在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库。所谓第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。如果出现重复的属性,就可能需要定义一个新的实体,新的实体由重复的属性构成,新实体与原实体之间为一对多关系。在第一范式(1NF)中表的每一行只包含一个实例的信息。例如,对于员工信息表,不能将员工信息都放在一列中显示,也不能将其中的两列或多列在一列中显示;员工信息表的每一行只表示一个员工的信息,一个员工的信息在表中只出现一次。简而言之,第一范式就是无重复的行,并且列不可再分。
2 第二范式(2NF)
第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或行必须可以被惟一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。员工信息表中加上了员工编号(emp_id)列,因为每个员工的员工编号是惟一的,因此每个员工可以被惟一区分。这个惟一属性列被称为主关键字或主键、主码。第二范式(2NF)要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。简而言之,第二范式就是非主键列必须依赖于主键列。第二范式(2NF)值得注意的是:“NF2要求在数据库设计时,每个表中的信息,只能是自己实体所拥有的信息。”
eg:属性1必须依赖于属性2:属性1,一定是属性2所代表的实体“天生”具有的。
学号 | 姓名 | 兴趣1 | 兴趣2 |
1 | a | 打球 | 打豆豆 |
2 | b | 开车 | 开玩笑 |
* from 班级表 c , 学生表 s where c.班级编号=s.班级编号。但是表连接会让计算机做大量的匹配和计算,所以是比较消耗资源(资源主要是指CPU和内存)。为了提高效率,所以可以违反NF2,将表格如下:
班级表 | |
班级编号 | 班级名称 |
学生表 | |||
学号 | 姓名 | 班级编号 | 班级姓名 |
3 第三范式(3NF)
在满足了第一范式和第二范式的基础只上,可以满足第三范式,第三范式简而言之,就是非主键列之间是相对独立的。先看一张表。
学号 | 姓名 | 出生日期 | 生肖 |
1 | 张三 | 1980-01-02 | 猴 |
2 | 李四 | 1983-04-02 | 牛 |
3 | 王五 | 1988-11-02 | 牛 |
生肖编号 | 生肖名称 |
1 | 猴 |
2 | 牛 |
NF1 行不可重复,列不可再分 - 必须满足
NF2 非主键列必须依赖于主键列 - 必须满足
NF3 非主键列之间必须相互独立 - NF3可以不满足
相关文章推荐
- IOS数据库的一些了解操作
- Hibernate-note03
- nodejs 使用 generic-pool 操作 redis数据库
- MySQL 普通索引、唯一索引和主索引
- Oracle如何实现跨库查询
- oracle between and 边界问题
- MySQL之选择字段数据类型
- Redis01初识
- mysql存储过程-递归赋值国家地区
- mysql之Truncate 和Delete语句删除表的所有记录
- Redis教程5--Redis排序
- Redis教程6--Redis事务
- 修改MySql最大Sql文件导入大小
- redis持久化RDB和AOF
- Centos6.5 安装 MariaDB-10.0.20-linux-x86_64.tar.gz
- Linux系统(X64)安装Oracle11g
- sql注入定义、原理、攻击和防护
- Linux下Redis服务器安装配置
- 无法创建磁盘数据库报错ora-01031 insufficient privileges
- 修改MySQL数据库字符编码为UTF-8解决中文乱码