知识大全 数据库设计三大范式应用实例剖析
Posted 范式
篇首语:采得百花成蜜后,为谁辛苦为谁甜。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 数据库设计三大范式应用实例剖析相关的知识,希望对你有一定的参考价值。
引言
数据库的设计范式是数据库设计所需要满足的规范 满足这些规范的数据库是简洁的 结构明晰的 同时 不会发生插入(insert) 删除(delete)和更新(update)操作异常 反之则是乱七八糟 不仅给数据库的编程人员制造麻烦 而且面目可憎 可能存储了大量不需要的冗余信息
设计范式是不是很难懂呢?非也 大学教材上给我们一堆数学公式我们当然看不懂 也记不住 所以我们很多人就根本不按照范式来设计数据库
实质上 设计范式用很形象 很简洁的话语就能说清楚 道明白 本文将对范式进行通俗地说明 并以笔者曾经设计的一个简单论坛的数据库为例来讲解怎样将这些范式应用于实际工程
范式说明
第一范式( NF) 数据库表中的字段都是单一属性的 不可再分 这个单一属性由基本类型构成 包括整型 实数 字符型 逻辑型 日期型等
例如 如下的数据库表是符合第一范式的
而这样的数据库表是不符合第一范式的
很显然 在当前的任何关系数据库管理系统(DBMS)中 傻瓜也不可能做出不符合第一范式的数据库 因为这些DBMS不允许你把数据库表的一列再分成二列或多列 因此 你想在现有的DBMS中设计出不符合第一范式的数据库都是不可能的
第二范式( NF) 数据库表中不存在非关键字段对任一候选关键字段的部分函数依赖(部分函数依赖指的是存在组合关键字中的某些字段决定非关键字段的情况) 也即所有非关键字段都完全依赖于任意一组候选关键字 假定选课关系表为SelectCourse(学号 姓名 年龄 课程名称 成绩 学分) 关键字为组合关键字(学号 课程名称) 因为存在如下决定关系
(学号 课程名称) → (姓名 年龄 成绩 学分)
这个数据库表不满足第二范式 因为存在如下决定关系
(课程名称) → (学分)
(学号) → (姓名 年龄)
即存在组合关键字中的字段决定非关键字的情况
由于不符合 NF 这个选课关系表会存在如下问题
( ) 数据冗余
同一门课程由n个学生选修 学分 就重复n 次 同一个学生选修了m门课程 姓名和年龄就重复了m 次
( ) 更新异常
若调整了某门课程的学分 数据表中所有行的 学分 值都要更新 否则会出现同一门课程学分不同的情况
( ) 插入异常
假设要开设一门新的课程 暂时还没有人选修 这样 由于还没有 学号 关键字 课程名称和学分也无法记录入数据库
( ) 删除异常
假设一批学生已经完成课程的选修 这些选修记录就应该从数据库表中删除 但是 与此同时 课程名称和学分信息也被删除了 很显然 这也会导致插入异常
把选课关系表SelectCourse改为如下三个表
学生 Student(学号 姓名 年龄)
课程 Course(课程名称 学分)
选课关系 SelectCourse(学号 课程名称 成绩)
这样的数据库表是符合第二范式的 消除了数据冗余 更新异常 插入异常和删除异常
另外 所有单关键字的数据库表都符合第二范式 因为不可能存在组合关键字
第三范式( NF) 在第二范式的基础上 数据表中如果不存在非关键字段对任一候选关键字段的传递函数依赖则符合第三范式 所谓传递函数依赖 指的是如果存在 A → B → C 的决定关系 则C传递函数依赖于A 因此 满足第三范式的数据库表应该不存在如下依赖关系
关键字段 → 非关键字段x → 非关键字段y
假定学生关系表为Student(学号 姓名 年龄 所在学院 学院地点 学院电话) 关键字为单一关键字 学号 因为存在如下决定关系
(学号) → (姓名 年龄 所在学院 学院地点 学院电话)
这个数据库是符合 NF的 但是不符合 NF 因为存在如下决定关系
(学号) → (所在学院) → (学院地点 学院电话)
即存在非关键字段 学院地点 学院电话 对关键字段 学号 的传递函数依赖
它也会存在数据冗余 更新异常 插入异常和删除异常的情况 读者可自行分析得知
把学生关系表分为如下两个表
学生 (学号 姓名 年龄 所在学院)
学院 (学院 地点 电话)
这样的数据库表是符合第三范式的 消除了数据冗余 更新异常 插入异常和删除异常
鲍依斯 科得范式(BCNF) 在第三范式的基础上 数据库表中如果不存在任何字段对任一候选关键字段的传递函数依赖则符合第三范式 假设仓库管理关系表为StorehouseManage(仓库ID 存储物品ID 管理员ID 数量) 且有一个管理员只在一个仓库工作 一个仓库可以存储多种物品 这个数据库表中存在如下决定关系
(仓库ID 存储物品ID) →(管理员ID 数量)
(管理员ID 存储物品ID) → (仓库ID 数量)
所以 (仓库ID 存储物品ID)和(管理员ID 存储物品ID)都是StorehouseManage的候选关键字 表中的唯一非关键字段为数量 它是符合第三范式的 但是 由于存在如下决定关系
(仓库ID) → (管理员ID)
(管理员ID) → (仓库ID)
即存在关键字段决定关键字段的情况 所以其不符合BCNF范式 它会出现如下异常情况
( ) 删除异常
当仓库被清空后 所有 存储物品ID 和 数量 信息被删除的同时 仓库ID 和 管理员ID 信息也被删除了
( ) 插入异常
当仓库没有存储任何物品时 无法给仓库分配管理员
( ) 更新异常
如果仓库换了管理员 则表中所有行的管理员ID都要修改
把仓库管理关系表分解为二个关系表
仓库管理 StorehouseManage(仓库ID 管理员ID)
仓库 Storehouse(仓库ID 存储物品ID 数量)
这样的数据库表是符合BCNF范式的 消除了删除异常 插入异常和更新异常 范式应用
我们来逐步搞定一个论坛的数据库 有如下信息
( ) 用户 用户名 email 主页 电话 联系地址
( ) 帖子 发帖标题 发帖内容 回复标题 回复内容
第一次我们将数据库设计为仅仅存在表
这个数据库表符合第一范式 但是没有任何一组候选关键字能决定数据库表的整行 唯一的关键字段用户名也不能完全决定整个元组 我们需要增加 发帖ID 回复ID 字段 即将表修改为
这样数据表中的关键字(用户名 发帖ID 回复ID)能决定整行
(用户名 发帖ID 回复ID) → (email 主页 电话 联系地址 发帖标题 发帖内容 回复标题 回复内容)
但是 这样的设计不符合第二范式 因为存在如下决定关系
(用户名) → (email 主页 电话 联系地址)
(发帖ID) → (发帖标题 发帖内容)
(回复ID) → (回复标题 回复内容)
即非关键字段部分函数依赖于候选关键字段 很明显 这个设计会导致大量的数据冗余和操作异常 我们将数据库表分解为(带下划线的为关键字)
( ) 用户信息 用户名 email 主页 电话 联系地址
( ) 帖子信息 发帖ID 标题 内容
( ) 回复信息 回复ID 标题 内容
( ) 发贴 用户名 发帖ID
( ) 回复 发帖ID 回复ID
这样的设计是满足第 范式和BCNF范式要求的 但是这样的设计是不是最好的呢?
不一定
观察可知 第 项 发帖 中的 用户名 和 发帖ID 之间是 N的关系 因此我们可以把 发帖 合并到第 项的 帖子信息 中 第 项 回复 中的 发帖ID 和 回复ID 之间也是 N的关系 因此我们可以把 回复 合并到第 项的 回复信息 中 这样可以一定量地减少数据冗余 新的设计为
( ) 用户信息 用户名 email 主页 电话 联系地址
( ) 帖子信息 用户名 发帖ID 标题 内容
( ) 回复信息 发帖ID 回复ID 标题 内容
数据库表 显然满足所有范式的要求
数据库表 中存在非关键字段 标题 内容 对关键字段 发帖ID 的部分函数依赖 即不满足第二范式的要求 但是这一设计并不会导致数据冗余和操作异常
数据库表 中也存在非关键字段 标题 内容 对关键字段 回复ID 的部分函数依赖 也不满足第二范式的要求 但是与数据库表 相似 这一设计也不会导致数据冗余和操作异常
由此可以看出 并不一定要强行满足范式的要求 对于 N关系 当 的一边合并到N的那边后 N的那边就不再满足第二范式了 但是这种设计反而比较好!
对于M N的关系 不能将M一边或N一边合并到另一边去 这样会导致不符合范式要求 同时导致操作异常和数据冗余 对于 的关系 我们可以将左边的 或者右边的 合并到另一边去 设计导致不符合范式要求 但是并不会导致操作异常和数据冗余
结论
满足范式要求的数据库设计是结构清晰的 同时可避免数据冗余和操作异常 这并意味着不符合范式要求的设计一定是错误的 在数据库表中存在 或 N关系这种较特殊的情况下 合并导致的不符合范式要求反而是合理的
cha138/Article/program/SQL/201311/16402相关参考
数据库设计是应用程序设计的基础其性能直接影响应用程序的性能数据库性能包括存储空间需求量的大小和查询响应时间的长短两个方面为了优化数据库性能需要对数据库中的表进行规范化规范化的范式可分为第一范式第二
PHPWeb开发学习实录:数据类型实例应用 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &nb
系统性红斑狼疮这种疾病的产生,有其致病因素,大致可以列为三类,比如遗传,环境因素和雌性激素的作用。这三种病因相互作用,可以单独,也可以并发存在。下面,我们就系统性红斑狼疮的三大基本病因做相关的阐述。1
.Net编写类库直接操作MySql数据库应用实例 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
Oracle数据字典的介绍与应用实例 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! Oracle
栈与队列的比较 栈与递归cha138/Article/program/sjjg/201311/23214
第三范式并不是至高无上 另一方面开发人员对数据库的一知半解可能是一件比较危险的事情我看到过很多数据库被设计得过于死板这些数据库的设计者坚持把所有东西都放在查询表中 是的数据库开发者需要知道规范
JSP编程进度条设计实例 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 许多Web应用企业应
成交堆积的应用实例区域统计显示,1999年6月18日至10月15日,深、沪两市成交总金额分别为8076亿和9511亿。区域统计给出了一个准确的量化数据,而“成交堆积”则给出了一个直观的图示化分析结果。
知识大全 剖析Access数据库升迁SQL Server问题
剖析Access数据库升迁SQLServer问题 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!