数据库范式
范式用于规定关系数据库表结构的一种规范,以减小数据的冗余。
范式主要有以下几种:
BCNF范式∈第三范式∈第二范式∈第一范式
它们之间是一个子集关系,满足第二范式必满足第一范式
下面就来仔细说说这些范式:
一、 第一范式
通俗的说就是数据库中不能表中有表,某一列中不能再嵌套其他列,请看下面这个表结构
学号 | 姓名 | 院系及专业 | |
学院 | 专业 |
院系及专业这一列里又嵌套了两列就不符合第一范式
改正:
学号 | 姓名 | 院系 | 专业 |
这样学生表就符合第一范式
二、 第二范式
主键如果是多个列组合起来的,找不到一列完全依赖于部分主键
比如这样一张表
学生 | 课程 | 老师 | 老师职称 | 教材 | 教室 | 上课时间 |
某学生上一门课,上课的地点、老师、老师的职称、所用教材、时间一定是确定的,那么(学生、课程)联合起来组成了该表的主键
但是(课程à教材),就找到了一列完全依赖于部分主键
?这样的部分依赖会造成什么样的影响呢
1)数据冗余
共有m个学生选《数据结构》这门课,那么数据结构的教材就要出现m次
2)更新异常
①如果要修改《数据结构》这一门课的教材,那么就得把所有选该课的记录都要修改,太麻烦了
②如果有学生没有选课,那么该学生的信息无法加入
③如果有的课程没有学生选,那么该课程的信息无法查询
3)删除异常
如果某学生撤消了选课记录,重新选择,那么在删除选课记录时将课程信息也删除了找不到该课程所用的教材
→→→改正:
将上表分离成两个表:
学生 | 课程 | 老师 | 老师职称 | 教师 | 上课时间 |
课程 | 教材 |
三、第三范式-------不能有传递依赖
在上面
学生 | 课程 | 老师 | 老师职称 | 教师 | 上课时间 |
?产生的影响
① 老师职称改变,需要在表中修改很多次
② 某学生不选哪个老师的课,该老师的职称信息无从查找
③ 某老师刚来学校报到,现无学生选他的课那么该老师的信息无法插入到表中
→→→改正:
将表继续拆分为两个表
学生 | 课程 | 老师 | 教室 | 上课时间 |
老师 | 老师职称 |
四、BCNF范式
【该部分内容引自百度空间http://hi.baidu.com/cy005/item/feea7816f399ce3db93180a2】
鲍依斯-科得范式(BCNF):在第三范式的基础上,数据库表中如果不存在任何字段对任一候选关键字段的传递函数依赖则符合第三范式。
假设仓库管理关系表为StorehouseManage(仓库ID, 存储物品ID, 管理员ID, 数量),且有一个管理员只在一个仓库工作;一个仓库可以存储多种物品。这个数据库表中存在如下决定关系:
(仓库ID, 存储物品ID) →(管理员ID, 数量)
(管理员ID, 存储物品ID) → (仓库ID, 数量)
所以,(仓库ID, 存储物品ID)和(管理员ID, 存储物品ID)都是StorehouseManage的候选关键字,表中的唯一非关键字段为数量,它是符合第三范式的。但是,由于存在如下决定关系:
(仓库ID) → (管理员ID)
(管理员ID) → (仓库ID)
即存在关键字段决定关键字段的情况,所以其不符合BCNF范式。它会出现如下异常情况:
(1) 删除异常:
当仓库被清空后,所有"存储物品ID"和"数量"信息被删除的同时,"仓库ID"和"管理员ID"信息也被删除了。
(2) 插入异常:
当仓库没有存储任何物品时,无法给仓库分配管理员。
(3) 更新异常:
如果仓库换了管理员,则表中所有行的管理员ID都要修改。
把仓库管理关系表分解为二个关系表:
仓库管理:StorehouseManage(仓库ID, 管理员ID);
仓库:Storehouse(仓库ID, 存储物品ID, 数量)。
这样的数据库表是符合BCNF范式的,消除了删除异常、插入异常和更新异常。