【系统设计】如何权衡范式与反范式设计

一、什么是范式设计与反范式设计

1.1、范式设计(Normalization)

定义:

范式设计是数据库设计中最基础的设计原则之一,它主要通过规范化数据模型,减少数据冗余和数据不一致的问题。

常用的范式

  1. 第一范式(1NF):要求数据库中的每个字段都是原子性的,即每个字段都是一个不可再分的数据项。例如,学生的姓名和成绩应分别单独作为一个字段,而不是放在同一个字段中。

  2. 第二范式(2NF):要求数据库中的每个非主键字段都完全依赖于主键。这意味着非主键字段不能依赖于其他非主键字段。例如,在一个课程信息表中,如果学分依赖于学期而不是课程编号,那么就不符合第二范式。

  3. 第三范式(3NF):要求数据库中的每个非主键字段都不依赖于其他非主键字段。换句话说,非主键字段之间不应该存在传递依赖关系。例如,在订单信息表中,如果商品价格依赖于商品编号而不是订单号,那么就不符合第三范式。

目的:

  • 消除数据冗余,提高数据的一致性和完整性。

  • 降低数据维护成本,提升数据库的扩展性、容错性及可用性。

1.2、反范式设计(Denormalization)

定义:

反范式设计是根据具体业务需求灵活地对数据库进行设计,追求更高的性能和效率。它违反了范式中的一些规则,允许部分数据的冗余和冗长,以提高查询和操作的速度。

特点:

  • 允许数据冗余,以提高查询性能。

  • 适用于需要频繁读取数据且对写入性能要求不高的场景。

范式设计的对比:

  • 范式设计注重数据的规范化和减少冗余,而反范式设计则更注重查询性能。

  • 在某些情况下,反范式设计可能会导致数据更新和维护的复杂性增加,因为需要更新多个地方的数据以确保数据的一致性。

二、系统设计与Coding方面的思考

2.1、范式设计Join查询带来的影响

场景:查询该订单下的商品信息

查询SQL:

SELECT t_sku.sku_name FROM t_order 
LEFT JOIN t_sku ON t_order.sku_id = t_sku.id WHERE order.id = 1

有什么问题:(这也是互联网公司为什么建议采用单表查询的原因)

  • 如果关联的表比较多,性能会急剧下降,产生慢sql,慢sql对系统来说是致命的;

  • 考虑分库分表

    • 如果后面存储数据过大,需要采用分库分表方案,那我们需要对SQL进行重新改造,所带来的成本跟风险都蛮大的。

如果不采用SQL进行关联查询,采用在代码层面进行Join,会有什么影响?

查询代码如下:

SELECT sku_id FROM t_order WHERE id = 1SELECT id FROM t_sku WHERE id = id

会带来什么问题?

  • 如果数据量比较多,会对应用节点内存带来一定压力,甚至会带来FullGC

看到这里,我们其实可以用字段冗余来解决(反范式设计的体现)

我们可以在订单表里面冗余sku名称,这样就能实现需求,也能解决Join查询带来的挑战。

SELECT sku_name FROM t_order WHERE id = 1

2.2、冗余字段(反范式设计)带来的挑战

2.2.1、数据副本的一致性

  • 数据冗余:反范式化技术的主要特点之一是数据的冗余存储。这意味着相同的数据可能在多个表中都有副本。

  • 不一致的风险:当修改了某个数据副本而忘记更新其他副本时,数据就会出现不一致的情况。这种情况在更改频繁的数据中尤为突出。

更新操作的复杂性

  • 更新操作的复杂性:由于反范式化技术增加了数据冗余,每个副本都需要进行更新以维持一致性。这增加了更新操作的复杂度,并容易出错。

数据一致性的维护策略

  • 事务处理:使用事务来保证一致性,即要么所有相关的表都更新成功,要么都回滚到更新前的状态。

  • 定时器更新:在数据更新后,使用定时器来定时更新其他相关数据,确保数据的一致性。

  • 触发器:当数据被修改时,触发其他相关数据的修改,从而确保数据的一致性。

2.2.2、分布式事务

  • 数据冗余:反范式设计通过有意地冗余部分数据以提高查询性能。然而,在分库分表的场景中,这种冗余数据可能导致分布式事务的复杂性增加。

  • 一致性挑战:当修改一个数据副本时,需要确保所有相关副本都得到更新,以保持数据一致性。这涉及到跨多个数据库或数据表的事务操作。

分布式事务的复杂性

  • 跨库事务:当更新内容同时分布在不同库中时,会带来跨库事务问题。这些事务需要协调多个数据库节点,增加了事务的复杂性和执行时间。

  • 两阶段提交和XA协议:为了解决跨库事务问题,一般可使用“XA协议”和“两阶段提交”处理。这些方法虽然能最大限度保证数据库操作的原子性,但在提交事务时需要协调多个节点,推后了提交事务的时间点,延长了事务的执行时间。

分布式事务带来的其他问题

  • 性能影响:随着数据库节点的增多,分布式事务可能导致性能下降,因为每次事务都需要跨多个节点进行通信和协调。

  • 死锁和冲突:在分布式系统中,由于网络延迟和故障等因素,事务在访问共享资源时可能发生冲突或死锁,进一步增加了事务管理的复杂性。

解决方案和策略

  • 全局表:为了避免跨库join查询,可以将一些全局性的、较少修改的表(如“数据字典表”)在每个数据库中都保存一份。这样可以减少跨库事务的需求。

  • 字段冗余:一种典型的反范式设计,利用空间换时间,为了性能而避免join查询。但这种方法也增加了数据冗余和分布式事务的复杂性。

  • 最终一致性:对于性能要求高但对一致性要求不高的系统,可以采用最终一致性策略。即不苛求系统的实时一致性,而是在允许的时间段内达到最终一致性。这可以通过事务补偿、数据对账等方式实现。

2.2.3、CAP的权衡

  • 数据冗余:反范式设计通过增加数据冗余来提高查询性能。但在分库分表的场景中,这种冗余可能导致CAP权衡的复杂性增加。

一致性(Consistency)问题

  • 强一致性挑战:在分布式系统中,强一致性意味着所有节点在任何时候都看到相同的数据。然而,反范式设计引入的数据冗余可能导致在更新数据时,不同节点上的数据副本之间出现不一致。

  • 分布式事务的影响:为了保持数据的一致性,可能需要使用分布式事务来确保所有相关的数据副本都得到更新。然而,分布式事务的复杂性(如跨库事务、两阶段提交等)可能导致性能下降和可用性降低。

可用性(Availability)问题

  • 节点故障的影响:在分库分表的场景中,一个节点的故障可能导致部分数据无法访问。由于反范式设计引入了数据冗余,一个节点的故障可能影响到多个数据副本的可用性。

  • 维护数据一致性的代价:为了确保数据的一致性,可能需要采取额外的措施(如分布式锁、数据同步等),这些措施可能会降低系统的可用性。

分区容错性(Partition tolerance)问题

  • 网络分区的影响:在分布式系统中,网络分区是一个常见的问题。当网络分区发生时,系统需要能够继续运行并服务请求,即使部分节点之间无法通信。

  • 数据一致性与分区容错的权衡:在发生网络分区时,系统需要在一致性和可用性之间做出权衡。如果系统选择强一致性,可能会阻止写入操作直到所有节点都更新完成,这可能导致可用性降低。相反,如果系统选择可用性,可能会允许写入操作在部分节点上成功,但可能导致数据不一致。

解决方案和策略

  • 最终一致性:对于性能要求高但对一致性要求不高的系统,可以采用最终一致性策略。即不苛求系统的实时一致性,而是在允许的时间段内达到最终一致性。

  • 数据同步和补偿机制:为了保持数据的一致性,可以建立数据同步和补偿机制。例如,使用消息队列或日志来记录数据变更,并在后台异步地同步数据副本。

  • 分布式锁和协调服务:使用分布式锁和协调服务(如ZooKeeper、Etcd等)来协调不同节点之间的数据访问和更新操作,以确保数据的一致性。

2.3、使用场景权衡思考

数据库的范式设计与反范式设计各有其优点和适用场景。在选择使用哪种设计时,需要根据具体的业务需求、数据冗余情况、查询效率以及更新操作的频率等因素进行综合考虑。一般来说,如果业务场景对查询性能有较高要求且可以接受一定程度的数据冗余,那么反范式设计可能是一个不错的选择。而如果业务场景对数据的准确性和一致性有严格要求且希望减少数据冗余和维护成本,那么范式设计可能更为合适。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/31339.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

xv6 qemu 卡在Booting from Hard Disk...

定位到xv6目录下的kernel.ld的第25行 .stab:{ 修改成 .stab : AT(LOADADDR(.rodata) SIZEOF(.rodata)){

Netty中的各个关键时间点(一)

前置说明 本文主要记录Netty中的一些主要的关键时间点,是理解Netty 和 事件驱动的关键。也是阅读Netty源码的指导。 代码来源:Netty 4.1.77 本文涉及到的角色: 角色:主线程,主Reactor线程(bossGroup中的…

Linux连接工具MobaXterm详细使用教程

目录 一、MobaXterm的下载 1、访问官网 2、下载便携版 3、启动MobaXterm 二、MobaXterm基本使用设置 1、新建会话 2、使用ssh连接第一个会话 3、设置主密码 4、主界面 5、sftp文件上传下载 6、文件拖拽的上传下载 7.右键粘贴 8、查看服务器监测信息​编辑 9、个…

进军韩国5G市场!移远通信5G模组RG500L-EU率先获得KT、LGU+认证

近日,移远通信工规级5G模组RG500L-EU再传喜讯,率先通过了韩国两大运营商KT和LGU的严格认证。​在此之前,该模组已顺利通过KC认证(韩国法规认证),此次再获运营商认证表明,RG500L-EU已完全满足韩国…

LeetCode LCP 61. 气温变化趋势

别怕麻烦&#xff0c;模拟题有时候就是要多写一些条件&#xff08;或者你思维很活跃找出规律&#xff09;&#xff0c;代码如下&#xff1a; class Solution { public:int temperatureTrend(vector<int>& temperatureA, vector<int>& temperatureB) {int …

斗地主游戏

找了个斗地主的项目&#xff0c;github项目地址&#xff1a;https://github.com/zhuang0/BoYaDDZ/tree/master/BoyaDDZ。在此基础上做些修改和优化&#xff0c;为了方便国内访问&#xff0c;上传到gitee上。 gitee地址: https://gitee.com/zhagnjinaaaa/android-ddz v0.0.1解决…

Linux基础篇

Linux 本文章是在B站的尚课听的&#xff0c;但是由于版本较老&#xff0c;而且是以centOS学习Linux&#xff0c;由于CentOS在10天后就不再更新&#xff0c;被抛弃了&#xff0c;痛定思痛&#xff0c;及时停课。但是又不想浪费笔记&#xff0c;前来保存一下。 文章目录 Linux前…

个人介绍~

摘要 大家好&#xff0c;很高兴以这种方式见到大家。本篇文章可能会很长&#xff0c;如果您不喜欢长文章或者笔者&#xff0c;就早早出门右拐&#xff08;不喜勿喷&#xff09;。本篇会持续更新&#xff0c;记录个人从大学生涯到毕业后求职&#xff0c;工作&#xff0c;个人爱好…

mindspore打卡第三课模型定义和训练全流程

python import mindspore from mindspore import nn, ops class Network(nn.Cell): ### 先定义类合参数 需要初始化实例 def __init__(self): super().__init__() self.flatten nn.Flatten() self.dense_relu_sequential nn.SequentialCell(…

Jacob代码编写/部署的注意事项集

注意事项一&#xff1a; 慎用 ComThread.InitSTA(); ComThread.Release(); 因为经常会在 ComThread.Release(); 发生阻塞&#xff0c;导致程序一直卡在这里&#xff0c;不能被调用&#xff1b; 建议不要使用这个初始化和释放线程的代码&#xff0c;看似很高级&#xff0c;其…

Swift Combine — zip和combineLatest的理解与使用

Publisher 上还有一些其他的操作&#xff0c;比如 zip 和 combineLatest&#xff0c;能让我们在时序上对控制多个 Publisher 的结果进行类似 and 和 or 的合并&#xff0c;它们在构建复杂 Publisher 逻辑时也十分有用。 zip Publisher 中的 zip 和 Sequence 的 zip 相类似&am…

iOS政策解读之一丨App提交审核前注意事项必知

大家好&#xff0c;我是小编阿文。欢迎您关注我们&#xff0c;经常分享有关Android出海&#xff0c;iOS出海&#xff0c;App市场政策实时更新&#xff0c;互金市场投放策略&#xff0c;最新互金新闻资讯等文章&#xff0c;期待与您共航世界之海。 iOS企业出海所面临的主要挑战…

路由优先级

在网络管理中&#xff0c;“路由策略”和“策略路由”是两种不同的概念。路由策略通常指的是传统的路由协议 和静态路由等机制的优先级&#xff0c;而策略路由&#xff08;Policy-Based Routing, PBR&#xff09;则允许管理员基于特定 的策略&#xff08;如源地址、目标地址、…

高速异地组网怎么办理?

在当今信息化时代&#xff0c;跨地域的远程办公、远程教育、远程医疗等需求越来越多。而高速异地组网作为一种解决不同地区之间快速组建局域网的方法&#xff0c;被广泛应用。本文将介绍一款异地组网内网穿透产品——【天联】&#xff0c;并提供其办理流程。 【天联】组网是什…

JMeter详解

一、线程组 作用:线程组就是控制Imeter用于执行测试的一组用户 位置:右键点击测试计划’-->添加 -->线程(用户)--> 线程组 特点: 模拟多人操作线程组可以添加多个&#xff0c;多个线程组可以并行或串行取样器(请求)和逻辑控制器必须依赖线程组才能使用线程组下可以…

[广搜BFS] Pots

描述 You are given two pots, having the volume of A and B liters respectively. The following operations can be performed: FILL(i) fill the pot i (1 ≤ i ≤ 2) from the tap;DROP(i) empty the pot i to the drain;POUR(i,j) pour from pot i to po…

java -jar

java [JVM参数] -jar [jar文件路径] [应用参数&#xff0c;包括springboot特定参数]* JVM 参数必须在-jar之前 * 应用参数一般在jar文件路径之后java -jar excel.jar java -jar -Dloader.pathlibx /path/to/yourApp.jar java -jar -Dloader.pathlibx /path/to/yourApp.jar --…

Behind the Code:Polkadot 如何实现全球协作与去中心化治理?

2024 年 6 月 16 日&#xff0c;《Behind the Code: Web3 Thinkers》第二季第二集上线。本集中&#xff0c;ChaosDAO 联合创始人兼 Novasama Technologies 首席财务官 Leemo 深入探讨了 Polkadot 生态系统中的全球协作力量&#xff0c;以及这种协作如何推动去中心化治理的创新与…

聊聊语法糖

语法糖&#xff08;Syntactic sugar&#xff09;是指编程语言中添加的某种语法&#xff0c;这种语法对语言的功能没有影响&#xff0c;但更方便程序员使用&#xff0c;并能增加程序的可读性&#xff0c;减少代码出错的机会。 历史&#xff1a; 语法糖这一术语是由英国计算机科…

C++:你用过MultiIndex容器吗?

作为C开发者&#xff0c;我们对键值容器非常熟悉&#xff0c;例如std::set、std::map、std::unordered_map等。这些容器以其强大的功能和高效的性能&#xff0c;成为我们处理数据存储和检索任务时的得力助手。但是你用过多键容器&#xff08;MultiIndex&#xff09;吗&#xff…