【转载】数据库范式那些事
数据库范式那些事
简介
数据库范式在数据库设计中的地位一直很暧昧,教科书中对于数据库范式倒是都给出了学术性的定义,但实际应用中范式的应用却不甚乐观,这篇文章会用简单的语言和一个简单的数据库DEMO将一个不符合范式的数据库一步步从第一范式实现到第四范式。
范式的目标
应用数据库范式可以带来许多好处,但是最重要的好处归结为三点:
1.减少数据冗余(这是最主要的好处,其他好处都是由此而附带的)
2.消除异常(插入异常,更新异常,删除异常)
3.让数据组织的更加和谐…
但剑是双刃的,应用数据库范式同样也会带来弊端,这会在文章后面说到。
什么是范式
简单的说,范式是为了消除重复数据减少冗余数据,从而让数据库内的数据更好的组织,让磁盘空间得到更有效利用的一种标准化标准,满足高等级的范式的先决条件是满足低等级范式。(比如满足2nf一定满足1nf)
DEMO
让我们先从一个未经范式化的表看起,表如下:
先对表做一个简单说明,employeeId是员工id,departmentName是部门名称,job代表岗位,jobDescription是岗位说明,skill是员工技能,departmentDescription是部门说明,address是员工住址
对表进行第一范式(1NF)
如果一个关系模式R的所有属性都是不可分的基本数据项,则R∈1NF。
简单的说,第一范式就是每一个属性都不可再分。不符合第一范式则不能称为关系数据库。对于上表,不难看出Address是可以再分的,比如”北京市XX路XX小区XX号”,着显然不符合第一范式,对其应用第一范式则需要将此属性分解到另一个表,如下:
对表进行第二范式(2NF)
若关系模式R∈1NF,并且每一个非主属性都完全函数依赖于R的码,则R∈2NF
简单的说,是表中的属性必须完全依赖于全部主键,而不是部分主键.所以只有一个主键的表如果符合第一范式,那一定是第二范式。这样做的目的是进一步减少插入异常和更新异常。在上表中,departmentDescription是由主键DepartmentName所决定,但却不是由主键EmployeeID决定,所以departmentDescription只依赖于两个主键中的一个,故要departmentDescription对主键是部分依赖,对其应用第二范式如下表:
对表进行第三范式(3NF)
关系模式R<U,F> 中若不存在这样的码X、属性组Y及非主属性Z(Z Y), 使得X→Y,Y→Z,成立,则称R<U,F> ∈ 3NF。
简单的说,第三范式是为了消除数据库中关键字之间的依赖关系,在上面经过第二范式化的表中,可以看出jobDescription(岗位职责)是由job(岗位)所决定,则jobDescription依赖于job,可以看出这不符合第三范式,对表进行第三范式后的关系图为:
上表中,已经不存在数据库属性互相依赖的问题,所以符合第三范式
对表进行BC范式(BCNF)
设关系模式R<U,F>∈1NF,如果对于R的每个函数依赖X→Y,若Y不属于X,则X必含有候选码,那么R∈BCNF。
简单的说,bc范式是在第三范式的基础上的一种特殊情况,既每个表中只有一个候选键(在一个数据库中每行的值都不相同,则可称为候选键),在上面第三范式的noNf表中可以看出,每一个员工的email都是唯一的(难道两个人用同一个email??)则,此表不符合bc范式,对其进行bc范式化后的关系图为:
对表进行第四范式(4NF)
关系模式R<U,F>∈1NF,如果对于R的每个非平凡多值依赖X→→Y(Y X),X都含有候选码,则R∈4NF。
简单的说,第四范式是消除表中的多值依赖,也就是说可以减少维护数据一致性的工作。对于上面bc范式化的表中,对于员工的skill,两个可能的值是”C#,sql,javascript”和“C#,UML,Ruby”,可以看出,这个数据库属性存在多个值,这就可能造成数据库内容不一致的问题,比如第一个值写的是”C#”,而第二个值写的是”C#.net”,解决办法是将多值属性放入一个新表,则第四范式化后的关系图如下:
而对于skill表则可能的值为:
总结
上面对于数据库范式进行分解的过程中不难看出,应用的范式登记越高,则表越多。表多会带来很多问题:
1 查询时要连接多个表,增加了查询的复杂度
2 查询时需要连接多个表,降低了数据库查询性能
而现在的情况,磁盘空间成本基本可以忽略不计,所以数据冗余所造成的问题也并不是应用数据库范式的理由。
因此,并不是应用的范式越高越好,要看实际情况而定。第三范式已经很大程度上减少了数据冗余,并且减少了造成插入异常,更新异常,和删除异常了。我个人观点认为,大多数情况应用到第三范式已经足够,在一定情况下第二范式也是可以的。
由于本人对数据库研究还处于初级阶段,所以上述如有不当之处,还望高手不吝指教…
By CareySon
【转载】数据库范式那些事相关推荐
- (转载)数据库范式及宽表窄表理解
1.数据库设计的三大范式,转载地址:http://www.cnblogs.com/linjiqin/archive/2012/04/01/2428695.html 为了建立冗余较小.结构合理的数据库, ...
- 数据库范式的思考以及数据库的设计
数据库范式--通俗易懂[转] 数据库范式是数据库设计中必不可少的知识,没有对范式的理解,就无法设计出高效率.优雅的数据库.甚至设计出错误的数据库.而想要理解并掌握范式却并不是那 么容易.教科书中一般以 ...
- [范式]数据库-范式
目录 范式 1.第一范式(1NF):列不可再分 2.第二范式(2NF)属性完全依赖于主键 3.第三范式(3NF)属性不依赖于其它非主属性 属性直接依赖于主键 4.BCNF(Boyce Codd ...
- [数据库原理] 理清数据库范式(1NF、2NF、3NF、BCNF)
文章目录 数据库范式概念 第一范式(1NF) 第二范式(2NF) 不满足第2范式可能出现的问题 第三范式(3NF) NC范式(BCNF) 总结(考试要考) 数据库范式概念 数据库范式:Normal f ...
- 什么是数据库范式(NF)?从一范式到五范式分别是什么?
什么是数据库范式(NF)?从一范式到五范式分别是什么? 什么是数据库范式(NF)? 为了建立冗余较小.结构合理的数据库,设计数据库时必须遵循一定的规则.在关系型数据库中这种规则就称为范式.范式是符合某 ...
- 数据库范式解析(1NF 2NF 3NF BCNF)
数据库设计范式是关系型数据库的设计准则.其目的在于通过规划设计使得数据库结构合理,尽量减少数据冗余,消除存储异常,方便数据的插入.更新和删除操作.目前常用范式包括1NF(第一范式).2NF(第二范式) ...
- 数据库范式5nf_第四范式(4NF)| 数据库管理系统
数据库范式5nf Fourth normal form (4NF) is a normal form used in database normalization, in which there ar ...
- 从第一范式(2nf)到第二范式(3nf)_啥是数据库范式
前言: 关于数据库范式,时常有听说过,一直没有详细去了解.一般数据库书籍或数据库课程会介绍范式相关内容,范式也经常出现在数据库考试题目中.不清楚你是否对范式有比较清晰的了解呢?本篇文章我们一起来学习下 ...
- [转载]数据库外键的使用
[转载]数据库外键的使用 外键的作用: 保持数据一致性,完整性,主要目的是控制存储在外键表中的数据. 使两张表形成关联,外键只能引用外表中的列的值! 例如: a b 两个表 a表中存有客户号,客户名称 ...
最新文章
- 第一届中国三维视觉大会China3DV论文展示
- 最佳时间 (DOM编程艺术)
- Web.sitemap网站导航
- 拼字符串成为时间,和两个计算时间点的中间值
- 1812:网格_指导设计:网格的历史
- python 过滤文本中的标点符号(转)
- 第12章类和动态内存分配
- SpringBoot RESTful 应用中的异常处理小结
- 2018 为自己加油!
- 安卓蓝牙键盘按键映射_安卓手游键盘映射工具(凤凰系统键盘映射) v2.0 最新版...
- 计算机中年级排名怎么操作,智学网年级排名查看方法规则介绍
- PCIe扫盲——PCI总线的三种传输模式
- uniApp H5微信网页授权,微信支付
- signature=735f4378ec01919f23285d0d2557be19,OPENSSL编程 第二十章 椭圆曲线
- python3 把类似这样的 '\xe5\xae\x9d\xe9\xb8\xa1\xe5\xb8\x82' 转换成汉字
- css公共样式插入音乐,【超全】常用的css公共样式
- 机器人编程要学哪些知识
- aliexpress商品详情API接口(速卖通商品详情页面数据接口)
- Adobe Photoshop CC 2019 for Mac(版本介绍)
- Linux libusb USB开发(一)—— USB设备基础概念
热门文章
- 如何安全的停止一个线程
- python 顺序栈及基本操作
- 安卓修改动画效果--动画差值器TimeInterpolator
- 射影几何笔记4:证明的思路
- linux用echo重定向到文件,Linux – Bash将String重定向到文件
- sql backup database备份d盘_Oracle RMAN备份与恢复
- vue如何封装请求接口方法
- 计算机专业英语第3章,计算机专业英语教案第3章
- oracle sys 查询语句,Oracle EBS-SQL (SYS-7):表单个性化查询.sql
- python输出二进制数_二进制中1的个数(python)