不了解数据库范式,可别说自己设计过库表!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/jdk_wangtaida/article/details/97019484

前言:

对于初学者来说,可能日常大部分时间都用来写业务的增删改查数据库啦,然后自己写个建表语句就把表建了,但是在很多岗位JD(job description,职位描述)上会发现有参与过库表设计的要求。提到库表设计就得不得不说数据库范式啦,这篇文章就带大家了解下什么是数据库范式。

正文:

我们从什么是范式,这六种范式分别是什么,范式有什么作用三个角度展开来讲

一、什么是范式

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

目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。

-----------以上概念来自百度百科,传送门:https://baike.baidu.com/item/%E6%95%B0%E6%8D%AE%E5%BA%93%E8%8C%83%E5%BC%8F/7309898?fr=aladdin

通俗的理解:范式就是设计数据库时的一种规范。

二、这六种范式分别是什么

第一范式(1NF)是对属性的原子性:每一列属性都是不可再分的属性值,确保每一列的原子性

下表的解释:adress_tel是用户地址和联系方式,tel座机电话,phone是移动电话。

图1(不符合1NF)
图2(符合1NF)

我们根据上图可以理解下,其实所谓的保持每一列的原子性,每一列的字段记录的属性不可以在拆分,这个判断的标准根据你们业务来判断。但是切记不要设置的两列的属性相近或者相似或一样,尽量合并属性一样的列,确保不产生冗余数据。地址1和地址2就没有必要设成两列。

第二范式(2NF)是对记录的惟一性:在满足1NF后,要求表中的所有列,都必须依赖于主键,而不能有任何一列与主键没有关系,也就是一个表只描述一件事,每个表都要有主键。

下表的解释:order_id是订单id,room_id房间id,user_id是用户id,user_name是用户名字,user_phone是用户手机号,这是用户订房的一个场景。

图片3(不符合范式2NF)

这个表里虽然有主键order_id,但是room_num和user_name与主键没有关系。他们属于房间和用户的信息,所以破坏了第二范式。 

图片4(订房关系表)
图片5(用户信息表)
图片6(房间信息表)

我们根据上面的例子可以看出,如果按照图三所设置的表,会出现很多重复数据,一个人定一个房间他的信息就会重复一次,造成数据的冗余,我们可以把它拆分成订房关系表和用户信息表以及房间信息表,这样就会便于维护数据,一个表只做一件事。订房关系表只维护订单信息,不用关心用户和房间的具体信息,用户信息表只维护用户的信息,不涉及订单和房间的具体信息。房间表只维护房间表,不涉及用户和订单的具体信息。

不符合2NF会带来:数据冗余、更新异常、插入异常、删除异常问题

第三范式(3NF):必须先满足第二范式(2NF),要求表与表之间的关系要使用主键进行关联。

下表的解释:order_id是订单id,room_id房间id,user_id是用户id,user_name是用户名字,user_phone是用户手机号,这是用户订房的一个场景。

图片7(不符合范式3NF)

上图的订单信息和房间信息以及用户信息之间的关联就没有全部用主键进行关联,用户信息用了用户name,所以不符合第三范式。

图片8(符合范式3NF)

高度总结,第一范式就是数据库的字段不能出现冗余,第二范式每个表都要有主键,且表里的字段要和主键有直接关系。第三范式要求表与表之间的关联要通过主键去关联。

BCNF(修正的第三范式):BCNF理解起来可能比较难理解,所以还是先看下面的图:

下表的解释:storehouse_id是仓库id,product_id是产品id,user_id是仓库管理员id,quantity是仓库所存产品的数量,一个管理员只能管理一个仓库,一个仓库可以存储多种物品。

上图是符合3NF的,最后一个数量是这个仓库存这个产品的数量不是这个产品有多少数量。 但这样会存在问题,当仓库清空后,“所有存储物品id”和“数量”信息被删除的同时,“仓库id”和“管理员id”信息也被删除。

所以为了消除这种情况,这种仓库管理表里面不建议牵连到多张表,关联表里只涉及到两张表的时候就符合BCNF。

 这样上面提到的情况就不会把仓库和管理员之间的联系删除到了。

第四范式(4NF)处理相互独立多值的情况:我们还是先举个例子

有一个用户联系方式表,user_id是用户的id,phone是移动电话,call是座机

上表的设计符合3NF,但是如果出现一个用户有两个移动电话和两个座机,这种情况就违反了第四范式。第四范式当一个表中的非主属性互相独立时(3NF),这些非主属性不该存在相互影响的关系,若有多值就违反了第四范式。

 如果我想放弃第一个座机和第二个移动电话,处理数据就很麻烦,所以这张表设计成这样就可以解决这个问题啦

第五范式 (5NF)处理相互依赖多值的情况:是最终范式。消除了4NF中的连接依赖。第五范式有两个要求:

1.必须满足第四范式。

2.表必须可以分解为较小的表,除非那些表在逻辑上拥有与原始表相同的主键。

举个例子:销售信息表,sale_person是销售人员,vendor是供货商,product是商品

如果我们想维护好上面关系去设计表,符合第五范式的设计方式就是下面的

三、范式的作用是什么

是为了使结构更合理,消除存储异常,使数据冗余尽量小。便于插入、删除和更新。遵从概念单一化“一事一地”原则,即一个关系模式描述一个实体或实体间的一种联系。规范的实质就是概念的单一化。

但是切记不是范式的等级应用的越高,数据库的设计就是最优,等级越高意味着拆分的表越多,维护的表也越多,连接操作多张表,数据量巨大的时候会严重影响系统运行的性能。所以我们要在这之间取一个平衡,来达到数据库设计的较优,系统性能也达到了相对的优。

 总结:

前四个范式自我感觉理解还是很到位的,第五范式我有点没太理解,但是我个人觉得这个第五范式有点像周星驰演的《武状元苏乞儿》说的降龙十八掌的最后一式,就是把前十七式都打一遍,就是最后一式亢龙有悔,所以第五范式,就是把前四个范式用到的基础上,把表拆的在细分点,使表的功能尽量单一,使耦合度降低,就是第五范式最终式。

这篇博客真是写到凌晨,但是总结下自己理解的知识,还是很开心。所以毒鸡汤来了,希望我们学完知识一定不要忘了总结,安利一部我最近很喜欢看的电视剧《Level Up》!

我是阿达,一名喜欢分享知识的程序员,时不时的也会荒腔走板的聊一聊电影、电视剧、音乐、漫画,这里已经有338位小伙伴在等你们啦,感兴趣的就赶紧来点击关注我把,哪里有不明白或有不同观点的地方欢迎留言。 

猜你喜欢

转载自blog.csdn.net/jdk_wangtaida/article/details/97019484
今日推荐