数据库范式与反范式设计,是一门艺术

简介: 在日常业务研发过程中,我们常常需要与数据库表打交道。设计范式是数据表设计的基本原则,对于数据表的设计范式,我们特别容易忽略它的存在。很多时候,当数据库运行了一段时间之后,我们才发现数据表设计上有问题。然后重新调整数据表的结构,需要做数据迁移,还有可能影响程序处理的业务逻辑,甚至系统的正常服务运行。

前言


在日常业务研发过程中,我们常常需要与数据库表打交道。设计范式是数据表设计的基本原则,对于数据表的设计范式,我们特别容易忽略它的存在。很多时候,当数据库运行了一段时间之后,我们才发现数据表设计上有问题。然后重新调整数据表的结构,需要做数据迁移,还有可能影响程序处理的业务逻辑,甚至系统的正常服务运行。


其实在数据库表结构设计的初期时候,我们就需要重视数据表的设计。


1、数据库的设计范式


1.1 数据库的设计范式包括哪些呢?


我们在设计关系型数据库模型的时候,需要对关系内部各个属性之间联系的合理化程度进行定义,这就有了不同等级的规范要求,这些规范要求被称为范式(NF)。


范式简单理解即为:一张数据表的设计结构需要满足的某种设计标准的级别。


目前关系型数据库一共有 6 种范式,按照范式级别,从低到高分别是:1NF(第一范式)、2NF(第二范式)、3NF(第三范式)、BCNF(巴斯 - 科德范式)、4NF(第四范式)和 5NF(第五范式,又叫做完美范式)。


数据库的范式设计越高阶,冗余度就越低,同时高阶的范式一定符合低阶范式的要求,比如满足 2NF 的一定满足 1NF,满足 3NF 的一定满足 2NF,依次类推。


这么多的范式级别,那是不是都要符合呢?


一般来说数据表的设计应尽量满足 3NF。但也不绝对,有时候为了提高某些查询性能,我们还需要破坏范式规则,也就是反规范化。


1.2 范式设计


范式化模型要求满足下面三大范式:


  • 1NF(第一范式)指的是数据库表中的任何字段属性都是原子性的,不可再分

这种情况比较好理解,我们在设计某个字段的时候,对于字段 X 来说,就不能把字段 X 拆分成字段 X-1 和字段 X-2。


  • 2NF(第二范式)指的数据表里的非主属性都要和这个数据表的候选键有完全依赖关系


假设存在用户、商品两个数据模型


用户模型的主键是用户ID,那么用户模型其它字段都应该依赖于用户ID


商品模型的主键是商品ID,它和用户没有直接关系,则这个属性不应该放到用户模型,而应该放到“用户-商品”相关联的订单表中去。


  • 3NF(第三范式)在满足 2NF 的同时,模型非主键字段不能相互依赖


例如:订单表(订单ID,商品ID,用户ID,用户姓名)


初看该表没有问题,满足第二范式,每列都和主键列“订单编号”相关。再细看你会发现“用户姓名”和“用户ID”相关联,“用户ID”和“订单ID”又相关联,最后经过传递依赖,“用户姓名”和”订单ID”相关联。为了满足第三范式,应去掉订单表中“用户姓名”列,放入用户表中。


微信图片_20220607233950.png


总结一下:


  • 1NF 需要保证表中每个属性都保持原子性;


  • 2NF 需要保证表中的非主属性与候选键完全依赖;


  • 3NF 需要保证表中的非主属性与候选键不存在传递依赖。


2、反范式设计


尽管前面我们介绍了数据表的设计有很多范式,数据库设计范式越高阶,数据表就会越精细,数据的冗余度也就越少,在一定程度上可以让数据库在内部关联上更好地组织数据。但事实上,我们在设计数据表的时候却不一定要一定严格参照这些标准,有时候我们也需要采用反范进行优化,通过空间来换取时间。


既然范式是为了消除冗余,那么反范式就是通过增加冗余、聚合的手段来提升性能


反范式就是相对范式化而言的,换句话说,就是允许少量的冗余,通过空间来换时间。同时反范式优化也是一种改善慢查询的优化思路。


例如:上面用户、商品、订单表的例子

我们可以在订单表中冗余商品名称字段,这样我们可以通过用户关联查询到订单表之后,无需再次关联商品表而拿到商品名称。如:订单表(订单ID,商品ID,用户ID,商品名称)


2.1 反范式设计存在的问题


从上面的例子中可以看出,反范式设计可以通过空间换时间,提升查询的效率,但是反范式也会带来一些新问题。


主要问题包括:


  • 在数据量小的情况下,反范式不能体现性能的优势,可能还会让数据库的设计更加复杂;


  • 比如采用存储过程来支持数据的更新、删除等额外操作,很容易增加系统的维护成本。


2.2 反范式设计适用场景


那么反范式优化适用于哪些场景呢?


在现实工作中,我们经常需要一些冗余信息,比如订单中的收货人信息:用户姓名、手机号码以及收货地址等等。


其实每次发生的订单收货信息都属于历史快照信息,需要进行保存,但同时用户又可以随时修改自己的信息,这时保存这些冗余信息是非常有必要的。



结论:当冗余信息有价值或者能大幅度提高查询效率的时候,我们就可以采取反范式设计的优化。


总结


在日常我们的工作当中,需要遵守一定的规范,例如项目研发流程规范、项目汇报规范以及会议规范等等,这些规范虽然会叫人感觉存在一定的约束感,所以我们常常对规则加以调整灵活运用,这样可以保证工作的正确性和效率的保障性。


其实这与数据表的设计规范很像,我们既需要规范性,同时也要考虑到执行时的方便性。


范式设计与反范式设计堪称 一门设计 “艺术”,因为它没有标准答案...


范式本身没有优劣之分,只有适用场景不同。没有完美的设计,只有合适的设计,我们在数据表的设计中,还需要根据需求将范式和反范式混合使用。


微信图片_20220607233953.jpg

相关文章
|
3月前
|
存储 关系型数据库 MySQL
轻松入门MySQL:数据库设计之范式规范,优化企业管理系统效率(21)
轻松入门MySQL:数据库设计之范式规范,优化企业管理系统效率(21)
|
14天前
|
存储 数据库
数据库设计三范式
三范式设计的最终目的都是为了减少我们的工作量,所以说,尽管三范式是一种很好的指导规范,但在实际应用中,我们也不需要太局限在三范式中,更多的是应该从项目中出发,设计出合理的表结构。
|
30天前
|
存储 关系型数据库 数据库
关系型数据库设计范式:深入理解与实践
【7月更文挑战第20天】关系型数据库设计范式是数据库设计中的重要指导原则,它通过一系列规范来减少数据冗余、提高数据一致性和优化查询性能。在实际应用中,我们应该根据具体需求和数据特点,灵活选择和应用不同的范式级别,以构建高效、可靠和可扩展的数据库系统。同时,也需要注意范式设计带来的挑战和限制,根据实际情况进行权衡和调整。
|
1月前
|
存储 Java 数据库连接
数据库三范式详解及应用
数据库三范式详解及应用
|
1月前
|
存储 Java 数据管理
数据库三范式设计与规范化过程详解
数据库三范式设计与规范化过程详解
|
29天前
|
存储 SQL 关系型数据库
MySQL设计规约问题之在数据库设计中,为什么要适当考虑反范式的表设计
MySQL设计规约问题之在数据库设计中,为什么要适当考虑反范式的表设计
|
3月前
|
存储 关系型数据库 数据库
关系型数据库设计规范第一范式(1NF)
【5月更文挑战第14天】关系型数据库设计规范第一范式(1NF
59 8
|
3月前
|
关系型数据库 数据库
关系型数据库设计规范第二范式(2NF)
【5月更文挑战第14天】关系型数据库设计规范第二范式(2NF)
72 7
|
3月前
|
关系型数据库 数据库
关系型数据库设计规范第三范式(3NF)
【5月更文挑战第14天】关系型数据库设计规范第三范式(3NF)
52 3