在当前互联网流行架构下,Redis、MongoDB等非关系型数据库(NoSQL)正逐渐抢占更多的视野,然而正如其释义(Not Only SQL)所说,NoSQL在当前仍然只作为传统关系型数据库的补充。当前的的大部分持久化场景下,关系型数据库仍然占据不可替代的地位。因此,能够设计出规范合理的关系数据表也是所有后端程序员的必修功课,然而“规范合理”是否又有一个量化的指标呢?通常领域下答案是没有,但在关系数据库下还真的有,这就是我们常说的“数据库范式”。

  “来,你给翻译翻译,什么叫范式?”

    “不用翻译,就是范式啊!”

  “我让你翻译给我听,什么叫范式?”

    “范式就是一种最佳实践”

  “翻译翻译,什么叫**的范式?”

    “范式就是一种前人经过无数次实践与论证,得出的经验总结!”

  “我让你翻译翻译,什么**的叫**的范式?”

    “你最好这么干,不然就是你错了,得拉出去枪毙!”

  “哦,原来这就是范式啊!”

  说起数据库范式,目前关系数据库共有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式),我们普遍认为达到第三范式就是较为合理的设计方案了,本篇文章也主要针对前三个范式做一个通俗解释。

 

  标准的三大范式定义:

    第一范式:当关系模式R的所有属性都不能在分解为更基本的数据单位时,称R是满足第一范式的,简记为1NF。满足第一范式是关系模式规范化的最低要

求,否则,将有很多基本操作在这样的关系模式中实现不了。

    第二范式:如果关系模式R满足第一范式,并且R的所有非主属性都完全依赖于R的每一个候选关键属性,称R满足第二范式,简记为2NF。

    第三范式:如果关系模式R满足第范式,X是R的任意属性集,如果X非传递依赖于R的任意一个候选关键字,称R满足第三范式,简记为3NF。

 

  什么,定义太长了,还好下面有一个精简的版本:

    第一范式:表中不能有表,列中不能有列。

    第二范式:满足第一范式的基础上,消除非主属性对主属性的部分依赖。

    第三范式:满足第二范式的基础上,消除非主属性对任一主属性的传递依赖。

 

  以下将尝试对上面的释义做一个通俗的解释:

  第一范式:表中不能有表,列中不能有列。这是对关系数据表的基本要求,同时相信也没有人能够在物理上突破限制,真的在表里建出另一张子表。然而,逻辑上的“列中不能有列”却常常被人忽略。例如,记录用户信息的用户表中有一个字段realname,记录用户姓名,这在中国倒很常见,但若是放眼全球,很多国家以firstname,lastname来标记姓名,仍然坚持以一个字段来记录姓名便会常常出现问题。因此,并不是所有关系表都能轻松达到严格的第一范式哦!

  第二范式:举个反例,设计一张学分表,包含字段course_id(课程),stu_no(学号),score(学分),stu_name(姓名)。相信很多人看到这样的表结构很快就能感受到一股奇怪的力量,没错,就是stu_name乱入了,这张表的主属性是course_id和stu_no,score完全依赖于主属性,而stu_name却只依赖于stu_no不依赖于course_id,这便是部分依赖,因此,将stu_name移出表结构的过程就是消除非主属性对于主属性部分依赖的过程。

  第三范式:仍然以例为证,设计一张订单表,order_id(订单号),total_fee(总价),customer_id(顾客id),customer_name(顾客姓名)。其中主属性是order_id,其他属性全部依赖于order_id,因此可以认为当前表结构满足第二范式,然而,customer_id依赖于order_id,而customer_name又依赖于customer_id,这便导致了一条传递依赖,不满足第三范式,因此将customer_name移出表结构的过程就是消除非主属性对主属性的传递依赖的过程。

 

  Tips:本质上,数据库范式的演变过程就是去除冗余数据的过程,在实践中,了解三大范式对于数据库的设计将会大有裨益,但切记不能钻牛角尖,因为业务场景的复杂度不在数据库范式讨论的范围之内,如果一味强求数据库的设计规范,很容易增加数据库的设计和程序编码的复杂度,因此,适当合理的数据冗余也是可以接受的哦!遗憾的是,“适当合理的数据冗余”并没有量化的概念哦!

 

版权声明:本文为Jasonchan1994原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/Jasonchan1994/p/10471427.html