一、前言

设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,
各种范式呈递次规范,`越高的范式数据库冗余越小`。

二、范式简介

范式来自英文Normal form,简称NF。要想设计—个好的关系,必须使关系满足一定的约束条件,
此约束已经形成了规范,分成几个等级,一级比一级要求得严格。
满足这些规范的数据库是简洁的、结构明晰的,同时,不会发生插入(insert)、删除(delete)和更新(update)操作异常。
反之则是乱七八糟,不仅给数据库的编程人员制造麻烦,而且面目可憎,可能存储了大量不需要的冗余信息。
目前关系数据库有六种范式:
第一范式(1NF)
第二范式(2NF)
第三范式(3NF)
巴斯-科德范式(BCNF)
第四范式 (4NF)
第五范式(5NF,又称完美范式)。
`满足最低要求的范式是第一范式(1NF)`。在第一范式的基础上进一步满足更多规范要求的称为第二范式(2NF),其余范式以次类推。
一般来说,`数据库只需满足第三范式(3NF)就行了`。

三、各类范式

3.1 第一范式(保证原子性)

所谓第一范式(1NF)是指在关系模型中,对于添加的一个规范要求,所有的域都应该是`原子性`的,
即数据库表的每一列都是不可分割的原子数据项,而不能是集合,数组,记录等`非原子数据项`。
即实体中的某个属性有多个值时,必须拆分为不同的属性。
在符合第一范式(1NF)表中的每个域值只能是`实体的一个属性或一个属性的一部分`。
简而言之,第一范式就是无`重复的域`。
**说明**:在任何一个关系数据库中,第一范式(1NF)是对关系模式的设计基本要求,`一般设计中都必须满足第一范式(1NF)`。
不过有些关系模型中突破了1NF的限制,这种称为非1NF的关系模型。
换句话说,是否必须满足1NF的最低要求,主要依赖于所使用的关系模型。

举例对如下用户表拆分成满足第一范式的表:

拆分后:

3.2 第二范式(单表拆分)

2NF是对记录的`惟一性`,要求记录有惟一标识,即实体的惟一性,即不存在部分依赖;
在1NF的基础上,非码属性必须完全依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖)
第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。
第二范式(2NF)要求数据库表中的每个实例或记录必须可以被唯一地区分。选取一个能区分每个实体的属性或属性组,作为实体的唯一标识。
例如在员工表中的身份证号码即可实现每个一员工的区分,该身份证号码即为候选键,任何一个候选键都可以被选作主键。
在找不到候选键时,可额外增加属性以实现区分,如果在员工关系中,没有对其身份证号进行存储,而姓名可能会在数据库运行的某个时间重复,
无法区分出实体时,设计辟如ID等不重复的编号以实现区分,被添加的编号或ID选作主键。(该主键的添加是在ER设计时添加,不是建库时随意添加)
第二范式(2NF)要求`实体的属性完全依赖于主关键字`。
所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,
新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的唯一标识。
简而言之,`第二范式就是在第一范式的基础上属性完全依赖于主键`。

举例对如下用户表拆分成满足第二范式的表:

上表满足第一范式,即每个字段不可再分,但是这张表设计得并不好,或者说,这张表的设计并不满足第二范式。
因为这张表里面描述了两件事情:学生信息、课程信息,`学分完全依赖于课程名称、姓名与年龄完全依赖于学号`。这么做的后果是:1、数据冗余:同一门课程由n个学生选修,"学分"重复n-1次;同一个学生选修了m门课程,姓名和年龄重复m-1次
2、更新异常:若调整了某门课程的学分,数据表中所有行的"学分"值都需要更新,否则会出现同一门课程学分不同的情况
3、插入异常:假设要开一门新课程,暂时没有人选修,那么由于没有"学号"关键字,"课程"与"学分"也无法记录入数据库
4、删除异常:假设一批学生已经完成课程的选修,这些选修记录就应该从数据库表中删除。但是,与此同时,"课程"和"学分"也被删除了,显然,这最终可能会导致插入异常

所以,此表的结构必须修改,修改后如下:

增加了表,将学生信息与课程信息通过一张中间表关联,很好地解决了上面的几个问题,
这就是第二范式的中心----`保证一张表只讲一件事情`。

3.3 第三范式(解决表字段冗余)

3NF是对字段的`冗余性`,要求任何字段不能由其他字段派生出来,它要求字段没有冗余,即不存在传递依赖;"保证每列都和主键直接相关"
在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)
第三范式(3NF)是第二范式(2NF)的一个子集,即`满足第三范式(3NF)必须满足第二范式(2NF`)。
简而言之,第三范式(3NF)要求一个关系中不包含已在其它关系已包含的非主关键字信息。
例如:
"存在一个部门信息表,其中每个部门有部门编号(dept_id)、部门名称、部门简介等信息。
那么在员工信息表中列出部门编号后就不能再将部门名称、部门简介等与部门有关的信息再加入员工信息表中。
如果不存在部门信息表,则根据第三范式(3NF)也应该构建它,否则就会有大量的数据冗余。"
简而言之:
`第三范式就是属性不依赖于其它非主属性,也就是在满足2NF的基础上,任何非主属性不得传递依赖于主属性。`

3.4 巴斯-科德范式

Boyce-Codd Normal Form(巴斯-科德范式)
在3NF基础上,任何非主属性不能对主键子集依赖(在3NF基础上消除对主码子集的依赖)
`巴斯-科德范式(BCNF)是第三范式(3NF)的一个子集,即满足巴斯-科德范式(BCNF)必须满足第三范式(3NF)`。
通常情况下,巴斯-科德范式被认为没有新的设计规范加入,只是对第二范式与第三范式中设计规范要求更强,`因而被认为是修正第三范式,`
也就是说,它事实上是对第三范式的修正,使数据库冗余度更小。这也是BCNF不被称为第四范式的原因。
某些书上,根据范式要求的递增性将其称之为第四范式是不规范,也是更让人不容易理解的地方。
而真正的第四范式,则是在设计规范中添加了对多值及依赖的要求

3.5 第四范式

对于第四范式,从理论层面来讲是,关系模式R∈1NF,
如果对于R对于R的每个非平凡多值依赖X→→Y(Y不属于X),X都含有候选码,则R∈4NF。
4NF就是限制关系模式的属性之间不允许有非平凡且非函数依赖的多值依赖。
`显然一个关系模式是4NF,则必为BCNF`。
也就是说,当一个表中的非主属性互相独立时(3NF),这些非主属性不应该有多值。若有多值就违反了第四范式。
`举例:`
"有这样一个用户联系方式表TELEPHONE(CUSTOMERID,PHONE,CELL)。CUSTOMERID为用户ID,PHONE为用户的固定电话,CELL为用户的移动电话。本来,这是一个非常简单的第3范式表。主键为CUSTOMERID,不存在传递依赖。但在某些情况下,这样的表还是不合理的"。比如说,用户有两个固定电话,两个移动电话。这时,表的具体表示如下:CUSTOMERID          PHONE           CELL1000               8828-1234     1490888888881000               8838-1234     149099999999由于PHONE和CELL是互相独立的,而有些用户又有两个和多个值。`这时此表就违反第四范式`。
在这种情况下,此表的设计就会带来很多维护上的麻烦。
例如,如果用户放弃第一行的固定电话和第二行的移动电话,那么这两行会合并吗?等等`解决问题的方法:`
设计一个新表NEW_PHONE(CUSTOMERID,NUMBER,TYPE).
这样就可以对每个用户处理不同类型的多个电话号码,而不会违反第四范式。显然,第四范式的应用范围比较小,因为只有在某些特殊情况下,要考虑将表规范到第四范式。
所以在实际应用中,一般不要求表满足第四范式。

3.6 第五范式

第五范式(5NF):是最终范式。消除了4NF中的连接依赖。第五范式有以下`要求`:
(1)必须满足第四范式
(2)表必须可以分解为较小的表,除非那些表在逻辑上拥有与原始表相同的主键。
第五范式是在第四范式的基础上做的进一步规范化。`第四范式处理的是相互独立的多值情况,而第五范式则处理相互依赖的多值情况`。
有一个销售信息表SALES(SALEPERSON,VENDOR,PRODUCT)。SALEPERSON代表销售人员,VENDOR代表供和商,PRODUCT则代表产品。
在某些情况下,这个表中会产生一些冗余。
可以将`表分解`为:
PERSON_VENDOR表(SALEPERSON,VENDOR);PERSON_PRODUCT表(SALEPERSON,PRODUCT);VENDOR­_PRODICT表(VENDOR,PRODUCT)

参考博客:

百度百科

https://zhuanlan.zhihu.com/p/72197799

https://zhuanlan.zhihu.com/p/59394493

https://www.cnblogs.com/xiaxianfei/p/5454707.html

关系数据库设计五大范式学习记录——<五>相关推荐

  1. Java学习记录五(多线程、网络编程、Lambda表达式和接口组成更新)

    Java学习记录五(多线程.网络编程.Lambda表达式和接口组成更新) Java 25.多线程 25.1实现多线程 25.1.1进程 25.1.2线程 25.1.3多线程的实现 25.1.4设置和获 ...

  2. MySQL学习记录 (五) ----- 存储函数、存储过程和触发器

    相关文章: <MySQL学习记录 (一) ----- 有关数据库的基本概念和MySQL常用命令> <MySQL学习记录 (二) ----- SQL数据查询语句(DQL)> &l ...

  3. UE4 学习记录五 使用合体触发器触发过场动画移动其他物体 开门

    这只是用来记录我学习UE4过程的,可能帮不到你,先说声抱歉.为了防止误导他人,请勿转载,请勿转载,请勿转载. 本文的主题是通过过场动画,实现物体移动并旋转,通过人物运动触发触发器,然后播放动画.总章目 ...

  4. WinFrom、C# 学习记录五 开发一个鼠标自动点击小软件

    一.说明 经常会被问到需要点击软件的,主要都是玩游戏的盆友,但是也有其它用途的.所以简单弄了一个,打算每当有时间,有需求,就加一些小功能. 这里主要是要记录一下相关开发工作,也记录一些使用/更新的信息 ...

  5. Redis设计与实现学习记录《一》

    文章目录 数据结构章节 SDS 数据结构 1.空间预分配 2.惰性空间释放 3.二进制安全 4.兼容部分C字符串函数 数据结构章节 数据库键总是一个字符串对象 数据库键的值可以是: 字符串对象 列表对 ...

  6. 《你好,放大器》----学习记录(五)

    5 典型放大电路分析 5.1 单电源线性变换电路 本节围绕表达式y = kx + b进行,这类电路是运放实现的最为简单的电路,也较为常用.其中,系数 k 指电压放大倍数(包含绝对值小于 1 的,称为衰 ...

  7. C++学习记录 五、C++提高编程

    再系统地过一次,夯实基础 学习目标: 过一遍黑马程序员C/C++学习视频 文章目录 学习目标: 学习内容: 一.C++基础入门 二.通讯录管理系统 三.C++核心编程 三. C++核心编程(面向对象) ...

  8. MFQPPDCS测试分析和测试设计框架l学习记录

    这几天在学习邰晓梅老师提出的MTQ-PPDCS测试框架,作为嵌入式软件测试从业人员,在测试框架学习过程中结合个人经历过的嵌入式软件测试项目,以思维导图形式梳理邰晓梅老师的框架理论,整理如下,希望通过进 ...

  9. gRPC学习记录(五)--拦截器分析

    对于此类调用拦截器是必不可少的,本篇就分析下拦截器的实现.(博主本来想分析源码的,但是水平不足,并发知识欠缺,看的不是很懂,哎,仍需努力),另外貌似不同版本有些差异,这里使用的是1.0.3版本. 1. ...

最新文章

  1. 转【红帽GFS集群文件系统配置指南】
  2. js字符串加密的几种方法
  3. Unity easyTouch移动代码(参考)
  4. Scrum介绍——续
  5. 次元网站女装穿起来,从A站到Z站,你知道哪个?谁才是你的最爱?
  6. c 语言常用宏定义 模板
  7. 阿里大数据分析与应用(part4)--一站式大数据平台DataWorks
  8. 使用Azure轻松实现Teams App的全球合规性
  9. Oracle行列转换的思考与总结
  10. android insmod命令,android的启动脚本(init.rc)文件的语法
  11. 【华为云技术分享】传统OCR识别综述
  12. 【SpringCloud】Spring cloud Alibaba Sentinel 系统规则
  13. Linux学习笔记---移植官方linux步骤(一)
  14. hbase的协处理器
  15. 超方便快捷搜索的油猴插件
  16. 如何让Bing(必应)快速收录你的网站
  17. java有abc三边求周长语句_java 给定三个点由三个点求三角形周长和面积
  18. 【极客时间-网络编程实战】
  19. 瑞鹄转债上市价格预测
  20. android蓝牙连接取消后怎么重新连上,重新启动后接收蓝牙连接更改

热门文章

  1. Verdi非常实用技巧
  2. 一个秒杀系统的设计思考(整体思考,收藏了)
  3. c语言中if(a字节4),【鲁班】的意思是什么?【鲁班】是什么意思?
  4. graphpad如何检测方差齐_看过来!GraphPad软件中的单因素方差分析这样用
  5. 上海亚商投顾:市场呈现窄幅震荡 新能源类行业受热炒
  6. css hat,论切图仔的自我修养
  7. Access在win10连接失败问题
  8. C++map和set
  9. kubernetes continually evict pod when node's inode exhausted
  10. Linux: 查看文件和文件夹大小的df和du命令