在当前互联网流行架构下,Redis、MongoDB等非关系型数据库(NoSQL)正逐渐抢占更多的视野,然而正如其释义(Not Only SQL)所说,NoSQL在当前仍然只做为传统关系型数据库的补充。当前的的大部分持久化场景下,关系型数据库仍然占据不可替代的地位。所以,可以设计出规范合理的关系数据表也是全部后端程序员的必修功课,然而“规范合理”是否又有一个量化的指标呢?一般领域下答案是没有,但在关系数据库下还真的有,这就是咱们常说的“数据库范式”。程序员
“来,你给翻译翻译,什么叫范式?”数据库
“不用翻译,就是范式啊!”后端
“我让你翻译给我听,什么叫范式?”架构
“范式就是一种最佳实践”编码
“翻译翻译,什么叫**的范式?”spa
“范式就是一种前人通过无数次实践与论证,得出的经验总结!”翻译
“我让你翻译翻译,什么**的叫**的范式?”设计
“你最好这么干,否则就是你错了,得拉出去枪毙!”ip
“哦,原来这就是范式啊!”ast
提及数据库范式,目前关系数据库共有六种范式:第一范式(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:本质上,数据库范式的演变过程就是去除冗余数据的过程,在实践中,了解三大范式对于数据库的设计将会大有裨益,但切记不能钻牛角尖,由于业务场景的复杂度不在数据库范式讨论的范围以内,若是一味强求数据库的设计规范,很容易增长数据库的设计和程序编码的复杂度,所以,适当合理的数据冗余也是能够接受的哦!遗憾的是,“适当合理的数据冗余”并无量化的概念呢!