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

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

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,一经查实,立即删除!

相关文章

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前…

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;被广泛应用。本文将介绍一款异地组网内网穿透产品——【天联】&#xff0c;并提供其办理流程。 【天联】组网是什…

JMeter详解

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

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

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

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

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

AI创作在论文写作中扮演什么角色?

近年来&#xff0c;随着科技的快速发展&#xff0c;AI已经逐渐渗透到了生活中的方方面面&#xff0c;其中也包含着学术领域。 作为学生党&#xff0c;你是否还在为期末论文&#xff0c;大学生实践报告而发愁&#xff1f; 有了这些AI写作神器&#xff0c;大学生们再也不用在期…

深度学习500问——Chapter11:迁移学习(3)

文章目录 11.3 迁移学习的常用方法 11.3.1 数据分布自适应 11.3.2 边缘分布自适应 11.3.3 条件分布自适应 11.3.4 联合分布自适应 11.3.5 概率分布自适应方法优劣性比较 11.3.6 特征选择 11.3.7 统计特征对齐方法 11.3 迁移学习的常用方法 11.3.1 数据分布自适应 数据分布自适…

Unity做一个剪辑声音的工具 在编辑器模式实时剪辑声音

Unity音频剪辑工具的实现 在游戏开发中&#xff0c;音频是一个至关重要的元素。音频剪辑工具能够帮助开发者高效地编辑和管理音频文件。本文将解析一个基于Unity编辑器的音频剪辑工具的实现方法 效果 工具功能 该音频剪辑工具允许用户在Unity编辑器中加载音频片段&#xff0…

Linux 一键部署 Nginx1.26.1 + ModSecurity3

前言 ModSecurity 是 Apache 基金会的一个开源、高性能的 Web 应用程序防火墙(WAF),它提供了强大的安全规则引擎,用于检测和阻止各种攻击行为,如 SQL 注入、XSS 跨站点脚本攻击等。而 nginx 是一个高性能的 Web 服务器,常用于处理大量的并发请求,具有很高的负载均衡能力…

如何修炼个人影响力,怎样有效地影响他人

一、教程描述 影响力是用一种别人所乐于接受的方式&#xff0c;改变他人的思想和行动的能力。影响力又被解释为战略影响、印象管理、善于表现的能力、目标的说服力以及合作促成的影响力等。影响力表明了一种试图支配与统帅他人的倾向&#xff0c;从而才使一个人采取各种劝说、…

iOS封装FrameWork

我们是整个项目封装给客户app用&#xff0c;项目里面有资源文件&#xff1a;xib和图片文件。有第三方&#xff0c;也有.a文件和第三方给我们的frameWork。下面记录下大体遇到的问题及遇到的冲突解决办法。 第一部分&#xff1a;封装frameWork 1.首先准备好&#xff0c;要封装的…

在阿里云服务器Linux系统上从头到尾实现Webapp的部署(安装卸载JDK、安装Tomcat、安装配置MySQL)

输入yum list | grep jdk 选择 devel是软件包中的典型命名格式 devel表示这个包是开发工具相关的 里面包含内容是最完整的 x86表示cpu架构是x86_64 还有openjdk表示开源版本 输入yum install java-1.8.0-openjdk-devel.x86_64 开始下载 遇到问你 is this ok? 输入y表示ok 输…

物联网APP设计艺术:技巧与未来科技的融合

从早期的智能家居&#xff0c;到今天的服装制造、医疗保健、物流运输、汽车工业...越来越多的行业开始使用物联网。物联网技术跨度大&#xff0c;适用范围广&#xff0c;设计师在面对物联网产品的UI设计项目时往往会感到受阻。这是什么原因呢&#xff1f;物联网应用程序界面设计…