实践千万条,基础第一条——数据库范式

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

 

(0)
上一篇 2022年3月22日
下一篇 2022年3月22日

相关推荐