一: 引言

作为一个数据库的学习者,搞懂关系数据库的三大范式是很有用的。然而教科书上有关数据库范式的介绍都是采用学术性的定义,语法羞涩,让人难懂,故写下自己对数据库范式的理解,给初学者提供帮助,也备日后查看。

本文不介绍规范化程度高于3NF的范式,因为其在实际应用中基本不会用到,原因也是很明显的(查询代价变大),因此,对于很多大型复杂的系统,其数据库设计都没有遵循所谓的范式,这也是为什么会出现所谓的逆规范化,好了,进入正题吧。

二: 范式介绍

    a:第零范式

第零范式就是指没有使用任何范式的设计,其添加数据的行为非常诡异,看看下表便知:

假设一个学生学习了三门课程,每门课程都有成绩,那么,采用第零范式的设计将会是如下情况                          

表a_0

这样的话,会使得往表中添加数据变得非常麻烦,每次添加一个新的数据,都要添加相应的字段,而且,因为表中其他的记录可能不需要这么多字段,因此会浪费

很多空间。如表a_1所示。

表a_1

         由此可以看出,不对数据库任用任何范式是非常愚蠢的,因为不仅会产生大量无用的表字段,而且会使得表结构非常难以维护。由此,引出第一范式的介绍

    b:  第一范式

第一范式就是在第零范式的基础上进行的改进,网上有很多人认为,所谓第一范式就是指表中的所有字段都是原子的、不可再分的,我个人认为此种理解也是正确的,原因不解释,我对第一范式的理解是,将

     第零范式中重复的字段抽取出来,作为表的数据,从而形成一个稳定的、冗余数据少得表结构。

由此,可以得出符合第一范式的表结构应该是:

此时,表的结构变得稳定了,而且表中的冗余信息相对第零范式也少了很多。可是,第一范式只是关系数据库设计的最低满足的范式,第一范式中仍然有很多的冗余信息,由此,需要引入第二范     式。

  c: 第二范式

第二范式是满足属性对主键是完全函数依赖的,因此,满足第二范式的表当然也是满足第一范式的,第二范式的目的就是消除表中的部分依赖。

这里,有几个概念要解释下,

1: 完全函数依赖

设有属性集K和P,若K中的所有属性共同能够推出P中的任意属性,且对于K的任何真子集,都不能推出P中的任意属性,则成K完全函数依赖P。

2: 部分函数依赖

与上相似,只是,K中存在真子集使得,该子集能推出p中任意属性。

概念性的东西,往往都难懂,举个例子,方便大家理解:

假如有一张学生成绩表,包含如下属性(学生Id,课程Id,课程分数,学生名字),其中,主键为(学生id,课程id),表中的数据如下:

那么,此时这张表的设计就不满足第二范式, 因为 主键(学生id,课程id) 能够唯一确定学生的姓名,因此,不满足属性完全函数依赖主键,因此不是第二范式。

从上面的表数据易知,不满足第二范式的表至少有以下几个缺点:

             1:数据重复,浪费空间,因为每存一条记录,都要存学生的名字,这样就是得存在大量重复的数据。

             2: 插入异常,若学生还没有成绩,那么这个学生就没有名字。

             3:  更新异常,删除异常等

        解决方法:

             将student_name字段放入学生表中,即消除表中的部分依赖。

   d: 第三范式

第三范式是指在满足第二范式的情况下,消除表中的传递依赖。

所谓传递依赖,就是指x–>y,y–>z,那么可以得到y–>z.

传递依赖常发生在主键、外键、外键相关的属性上,例如,假设有这样的表

学生表(学生id,学生姓名,院系id,院系名)  ,此处主键为(学生id),外键为(院系id)

院系表(院系id,院长名称),主键为 (院系id)

很明显,此处存在传递依赖,因为 学生id  可以唯一确定  院系id,而 院系id 可以唯一确定 院系名。

表中的数据如下

从上面的表数据易知,不满足第三范式的表至少有以下几个缺点:

1 :  数据重复,浪费空间,因为学生表每存一条记录,都会记录住院系的名字,存在大量的重复数据。

2:  插入异常,若新建一个院系,而该院系没有学生的话,该院系就没有名字。

3:  更新异常,删除异常等

三: 数据库设计的经验

       1: 表的数目不要太多,一般20-30张就够了。如果表的数目太多,则可以考虑采用同化操作,即将大体相同的实体放入到一张表中。

       2:当数据库中的信息非常庞大时,不要使用外键(逆规范化),因为由此可能带来非常大的性能损失。

       3:一般以消耗存储空间来换取效率。

 

数据库三大范式的理解相关推荐

  1. 浅谈数据库三大范式的理解

    首先声明一下,我的这个回答是个人工作总结,不适合考试答题昂. 欢迎关注我的博客. 前言:数据库设计其实不仅仅限制于三个范式,往下其实还有很多种,但对于大多数人来说,你又不搞科研,不造飞机大炮,掌握三大 ...

  2. 数据库三大范式通俗理解

    官方的解释就不放了,想看的可以去百度! 通俗的理解: 第一范式就是属性不可分割,每个字段都应该是不可再拆分的. 比如一个字段是姓名(NAME),在国内的话通常理解都是姓名是一个不可再拆分的单位,这时候 ...

  3. 数据库三大范式的理解(大白话篇)

    第一范式:列的原子性,即每一列(每一个属性,字段)都不可分割. 举例:销售成本=成本的单价*销售的数量,所以这里就不可以以销售成作为字段. 第二范式:非主属性必须完全依赖于主属性,不能存在只依赖于主属 ...

  4. mysql三大范式 答案_数据库三大范式定义与理解

    数据库三大范式定义与理解 发布时间:2018-06-04 10:24, 浏览次数:291 一.第一范式(1NF) 要求: 要求:每一个分量必须是不可分的数据项. 特点: 1)有主键,且主键不能为空. ...

  5. 数据库逻辑设计之三大范式通俗理解

    一.第一范式 1NF是对属性的原子性,要求属性具有原子性,不可再分解: 表:字段1. 字段2(字段2.1.字段2.2).字段3 ...... 如学生(学号,姓名,性别,出生年月日),如果认为最后一列还 ...

  6. 数据库三大范式(1NF,2NF,3NF)及ER图

    数据库三大范式(1NF,2NF,3NF)及ER图 百度官方解释: 设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据 ...

  7. 3nf mysql表_数据库三大范式(1NF,2NF,3NF)及ER图

    数据库三大范式(1NF,2NF,3NF)及ER图 百度官方解释: 设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据 ...

  8. Mysql数据库与数据库三大范式

    作者:左新宇 链接:https://zhuanlan.zhihu.com/p/59394493 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. MySQL 常用命令 ...

  9. 数据库三大范式详解,部分依赖、完全依赖、传递依赖

    数据库三大范式详解以及部分.完全.传递依赖 一.第一范式 二.第二范式 三.第三范式 四.部分依赖.完全依赖.传递依赖 完结撒花 一.第一范式 数据库每一列都是不可分的基本数据项(原子数据项) 就比如 ...

最新文章

  1. Fragment注入漏洞(CVE-2013-6271)检测
  2. 百度eCharts体验
  3. 启动VIP报CRS-1028/CRS-0223致使VIP状态为UNKNOWN故障分析与解决
  4. Android之解决viewpage加载第3个fragment的时候,第一个fragment又重新构建问题
  5. 【FFMPEG源码终极解析】 av_packet_alloc 与 av_packet_free
  6. 电脑显示器闪屏_Win7系统电脑显示器屏幕闪屏的解决办法
  7. PHP 报错 Use of undefined constant prop_values - ass...
  8. 201521123040《Java程序设计》第10周学习总结
  9. php foreach 循环 判断index 小于多少_Go 与 PHP 的语法对比
  10. 又涨价了!华为 P40系列海外售价曝光:还好国行版友好不少
  11. houdini 做选点效果
  12. Python与Redis集群的交互
  13. 目前为止微型计算机,2017年计算机一级考试题库及答案
  14. h5 iframe显示不全_干货|H5 唤醒APP小记
  15. MySQL存数学符号,如何将数学符号保存到mysql或mssql数据库?
  16. 2. HTTP 报文
  17. R语言和Python的区别
  18. NFC模组,开发NFC功能 只要几条指令的事情
  19. chrome浏览器谷歌浏览器打开是hao123
  20. 劳动法 第四章 工作时间和休息休假

热门文章

  1. java comm jar_串口开发 comm.jar | 学步园
  2. JSSE(Java SecuritySocket Extension,Java安全套接字扩展)
  3. Python零基础入门(五)
  4. Docker部署RabbitMQ
  5. [经验分享]TL431的应用及其封装乱象
  6. 如何正确理解TL431的工作方式
  7. spark报错 java.lang.NullPointerException: Null value appeared in non-nullable field:top level Product
  8. 入学校计算机社团申请书,入计算机协会申请书范文
  9. 【Python】回数是指从左向右读和从右向左读都是一样的数,例如12321,909。请利用filter()筛选出回数
  10. Android常用开源库