当前位置: 首页 > news >正文

数据库范式

本文系转载,原文地址:http://www.cnblogs.com/CareySon/archive/2010/02/16/1668803.html

简介

      数据库范式在数据库设计中的地位一直很暧昧,教科书中对于数据库范式倒是都给出了学术性的定义,但实际应用中范式的应用却不甚乐观,这篇文章会用简单的语言和一个简单的数据库DEMO将一个不符合范式的数据库一步步从第一范式实现到第四范式。

 

范式的目标

      应用数据库范式可以带来许多好处,但是最重要的好处归结为三点:

      1.减少数据冗余(这是最主要的好处,其他好处都是由此而附带的)

      2.消除异常(插入异常,更新异常,删除异常)

      3.让数据组织的更加和谐…

    

       但剑是双刃的,应用数据库范式同样也会带来弊端,这会在文章后面说到。

 

什么是范式

      简单的说,范式是为了消除重复数据减少冗余数据,从而让数据库内的数据更好的组织,让磁盘空间得到更有效利用的一种标准化标准,满足高等级的范式的先决条件是满足低等级范式。(比如满足2nf一定满足1nf)

 

DEMO

      让我们先从一个未经范式化的表看起,表如下:

0nf

先对表做一个简单说明,employeeId是员工id,departmentName是部门名称,job代表岗位,jobDescription是岗位说明,skill是员工技能,departmentDescription是部门说明,address是员工住址

对表进行第一范式(1NF)

    如果一个关系模式R的所有属性都是不可分的基本数据项,则R∈1NF。

    简单的说,第一范式就是每一个属性都不可再分。不符合第一范式则不能称为关系数据库。对于上表,不难看出Address是可以再分的,比如”北京市XX路XX小区XX号”,着显然不符合第一范式,对其应用第一范式则需要将此属性分解到另一个表,如下:

1nf

对表进行第二范式(2NF)

若关系模式R∈1NF,并且每一个非主属性都完全函数依赖于R的码,则R∈2NF

简单的说,是表中的属性必须完全依赖于全部主键,而不是部分主键.所以只有一个主键的表如果符合第一范式,那一定是第二范式。这样做的目的是进一步减少插入异常和更新异常。在上表中,departmentDescription是由主键DepartmentName所决定,但却不是由主键EmployeeID决定,所以departmentDescription只依赖于两个主键中的一个,故要departmentDescription对主键是部分依赖,对其应用第二范式如下表:

3nf

对表进行第三范式(3NF)

关系模式R<U,F> 中若不存在这样的码X、属性组Y及非主属性Z(Z  Y), 使得X→Y,Y→Z,成立,则称R<U,F> ∈ 3NF。

简单的说,第三范式是为了消除数据库中关键字之间的依赖关系,在上面经过第二范式化的表中,可以看出jobDescription(岗位职责)是由job(岗位)所决定,则jobDescription依赖于job,可以看出这不符合第三范式,对表进行第三范式后的关系图为:

3nf1

上表中,已经不存在数据库属性互相依赖的问题,所以符合第三范式

 

对表进行BC范式(BCNF)

关系模式R<U,F>∈1NF,如果对于R的每个函数依赖X→Y,若Y不属于X,则X必含有候选码,那么R∈BCNF。

简单的说,bc范式是在第三范式的基础上的一种特殊情况,既每个表中只有一个候选键(在一个数据库中每行的值都不相同,则可称为候选键),在上面第三范式的noNf表中可以看出,每一个员工的email都是唯一的(难道两个人用同一个email??)则,此表不符合bc范式,对其进行bc范式化后的关系图为:

bcnf

对表进行第四范式(4NF)

关系模式R<U,F>∈1NF,如果对于R的每个非平凡多值依赖X→→Y(Y  X),X都含有候选码,则R∈4NF。

简单的说,第四范式是消除表中的多值依赖,也就是说可以减少维护数据一致性的工作。对于上面bc范式化的表中,对于员工的skill,两个可能的值是”C#,sql,javascript”和“C#,UML,Ruby”,可以看出,这个数据库属性存在多个值,这就可能造成数据库内容不一致的问题,比如第一个值写的是”C#”,而第二个值写的是”C#.net”,解决办法是将多值属性放入一个新表,则第四范式化后的关系图如下:

4nf

而对于skill表则可能的值为:

4nfdemo

 

总结

     上面对于数据库范式进行分解的过程中不难看出,应用的范式登记越高,则表越多。表多会带来很多问题:

1 查询时要连接多个表,增加了查询的复杂度

2 查询时需要连接多个表,降低了数据库查询性能

而现在的情况,磁盘空间成本基本可以忽略不计,所以数据冗余所造成的问题也并不是应用数据库范式的理由。

因此,并不是应用的范式越高越好,要看实际情况而定。第三范式已经很大程度上减少了数据冗余,并且减少了造成插入异常,更新异常,和删除异常了。我个人观点认为,大多数情况应用到第三范式已经足够,在一定情况下第二范式也是可以的。

 

由于本人对数据库研究还处于初级阶段,所以上述如有不当之处,还望高手不吝指教…

 

By CareySon



相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • sed awk grep三剑客常用
  • 数据库事务隔离级别
  • 全排序算法
  • 用Spring+Junit4.4进行测试(使用注解)
  • Java HashMap 分析四篇连载
  • Leetcode 144. Binary Tree Preorder Traversal
  • 单页web应用是什么?它又会给传统网站带来哪些好处?
  • 深入理解HTML协议
  • BootStrap学习笔记
  • 深入解析 HTML DocumentType 元素
  • Android -- 获取网络数据并将数据存到本地数据库中
  • CSS选择符
  • Android 使用Socket进行通信(Android)
  • PythonNote01_HTML标签
  • CentOS7 搭建python3 Django环境
  • 03Go 类型总结
  • Angular 2 DI - IoC DI - 1
  • C++11: atomic 头文件
  • canvas 绘制双线技巧
  • Codepen 每日精选(2018-3-25)
  • Debian下无root权限使用Python访问Oracle
  • Idea+maven+scala构建包并在spark on yarn 运行
  • iOS 颜色设置看我就够了
  • mysql 数据库四种事务隔离级别
  • Node 版本管理
  • node-sass 安装卡在 node scripts/install.js 解决办法
  • Otto开发初探——微服务依赖管理新利器
  • Python socket服务器端、客户端传送信息
  • Python爬虫--- 1.3 BS4库的解析器
  • SSH 免密登录
  • 从零开始的webpack生活-0x009:FilesLoader装载文件
  • 开源SQL-on-Hadoop系统一览
  • 开源地图数据可视化库——mapnik
  • 如何借助 NoSQL 提高 JPA 应用性能
  • 优化 Vue 项目编译文件大小
  • 在 Chrome DevTools 中调试 JavaScript 入门
  • 怎样选择前端框架
  • Mac 上flink的安装与启动
  • MyCAT水平分库
  • ​Linux Ubuntu环境下使用docker构建spark运行环境(超级详细)
  • ​中南建设2022年半年报“韧”字当头,经营性现金流持续为正​
  • # Apache SeaTunnel 究竟是什么?
  • # Maven错误Error executing Maven
  • # 职场生活之道:善于团结
  • #1015 : KMP算法
  • #Datawhale AI夏令营第4期#AIGC方向 文生图 Task2
  • #我与虚拟机的故事#连载20:周志明虚拟机第 3 版:到底值不值得买?
  • (11)MSP430F5529 定时器B
  • (7)摄像机和云台
  • (DenseNet)Densely Connected Convolutional Networks--Gao Huang
  • (七)Flink Watermark
  • (区间dp) (经典例题) 石子合并
  • (一)【Jmeter】JDK及Jmeter的安装部署及简单配置
  • (一)Neo4j下载安装以及初次使用
  • (一)使用IDEA创建Maven项目和Maven使用入门(配图详解)