如何实现数据的正确拆分?

我们知道在传统的单块架构中,一个系统中只存在一个独立的服务和数据库实例。


上图中的系统架构实现起来比较简单,但是扩展性和伸缩性都比较差。因此,越来越多的系统开始采用了微服务架构。在微服务架构中,一个系统被拆分成多个服务,而每个服务都拥有属于自身的数据库。


从单块系统到微服务系统的转变过程需要根据领域对系统进行合理的拆分,同时也要求数据层面从集中式的管理转变为分散式的管理。这就引申出今天我们要讨论的主题,即数据拆分。

数据拆分场景和解决方案

设想我们现在拥有一个运行了一段时间的数据库实例,内部包含了多个数据库。那么我们可以想象通常都会存在跨表查询和跨库查询场景。同时,如何我们使用了存储过程等特定的数据库实现技术,那么想要实现对数据的拆分操作也会变得不那么容易。这些场景构成了我们实现数据拆分的主要场景。


接下来,我们将分别对上述场景进行分析,看看分别应该采用哪种解决方案。

跨表查询场景

在日常开发过程中,跨表查询是非常常见的一种实现技术。在同一个数据库中,开发人员可以通过主外键之间的关联关系完成多个表之间的连接操作。

下图展示了一种表连接的表现形式,图中的连接1所涉及到的表1和表2都属于同一个业务模块。对于这个连接,我们不需要进行数据去中心化,因为位于单个业务模块内部的数据连接查询不会影响到其他模块,符合微服务架构下服务拆分的基本原则。


我们再来看另一种连接情况。


可以看到连接2和连接1不同,该连接所涉及的表3和表4则位于两个不同的业务模块中。显然,当我们基于业务模块拆分微服务时,这种连接就不应该再存在。

针对跨多个业务模块的跨表查询应用场景,我们想要去掉表与表之间的连接也比较简单,因为表连接的本质就是把位于不同表中的数据进行组装,我们可以把这个组装过程放到内存中。也就是说,我们先分别从数据表中获取目标数据,然后通用代码在内存中完成数据的动态组装,然后在返回给客户端,整个过程如下图所示。


基于跨表查询场景下的分析,也可以得出一条在日常开发过程中的最佳实践,即我们应该尽量避免不同模块之间的数据产生数据表级别的关联,而是应该通过代码来管理和维护这层关系。

跨库查询场景

讨论完跨表查询,接下来我们讨论跨库查询场景。从系统设计角度而言,跨库查询是应该被明确禁止的,因此这种场景相对比较少。但如果一旦出现这种场景,那么所带来的问题也就更为严重。下图展示了跨库查询的具体场景。


一旦涉及到跨库查询,我们的基本思路就是对查询语句进行改造,通过接口查询的方式来替换跨库的查询连接。


现在,如果想要获取数据表1和表2中的数据,那么唯一的操作方法就是暴露API接口,应用程序通过接口获取数据之后再在内存中进行数据的组装,并开放给客户端进行访问。请注意,上图中所示的跨库查询和跨表查询方案的本质区别在于:位于不同数据库中的数据必须确保严格的边界,而通过接口的方式来获取数据可以做到这一点。这样,基于不同数据的不同接口可以面向各自的应用程序,这也为微服务的拆分奠定了基础。

关于跨库查询,还有一种特殊的应用场景。有时候,位于不同数据库中的数据虽然有一定的关联关系,但这种关联关系并不像连接查询那样需要实时失效,而是允许一定的时延性。这时候,通过接口的方法实时暴露数据就不是很有必要,我们可以采用数据定时同步的方式来完成跨库的数据同步。


可以看到,在这种应用场景下,数据库A和B中同时保存着表1和表2的数据,我们通过定时任务确保这两张表的数据是一致的。通过这种方式,原本需要跨库才能完成的查询,就转变成了单库内的数据查询,跨库查询就降级成了跨表查询。

技术耦合场景

当我们面对遗留系统时,一大挑战在于对一些数据库内置技术组件的改造,这些技术组件包括存储过程、触发器、函数等。由于技术体系的不断演进,我们已经不推荐把业务逻辑通过这些数据库内置技术组件进行实现,但在遗留系统改造过程中则非常常见。对于这些位于数据库内部的数据处理逻辑,开发人员唯一要做的就是把他们全部用业务代码的形式全部实现一遍即可。


数据拆分流程

理解了数据拆分的主要场景和对应的解决方案,我们接下来讨论如何实施这些解决方案。请注意,无论是实施对跨表查询、跨库查询还是遗留系统的改造,我们都需要确保线上业务的稳定性,而不是直接采用一刀切的方式进行直接替换。在今天的内容中,我们基于主流的微服务架构,以单个数据库拆分的场景为例来开展讨论。数据拆分前和拆分后的对比效果如下图所示。


可以看到,我们需要根据业务边界把单块系统拆分成多个微服务,然后基于服务边界进一步对数据库中的表进行拆分。最后,原本属于表之间的关联关系就变成了服务之间的接口对接关系。

在今天的内容中,我们把数据拆分的过程分成三个主要的步骤。

边界分离

要想拆分数据,首先需要拆分业务。根据业务模块的不同职责和内容,我们可以把单块系统中的代码拆分成不同的服务。


可以看到,我们从物理上拆分了服务A和服务B这两个微服务。其中服务A和服务B分别独享了表1和表2,但对于表3而言,服务A和服务B都需要访问。

数据冗余

为了对表3进行拆分,我们这时候就需要采用一定的数据冗余策略。


可以看到,我们需要把针对表3的数据操作抽象成“写”和“读”两方面。通常,这部分工作并不会很复杂,因为针对某个业务数据写入的源头通常只有一个,只要明确这个数据源即可。万一我们发现写的操作有多个源头,那么把这些源头的代码都放在微服务A中就可以了。至于读操作,我们确保采用一定的数据同步机制确保服务B中的表3数据实时更新即可。

接口改造

最后,我们明确了表3的“读写”边界,就可以通过接口的方式去除数据同步机制。这也是数据拆分的最后一个环节。


数据拆分是我们开展微服务架构设计和实现过程中的一种常见场景。应对这一场景的基本思路是分析服务与数据之间的关联关系,然后针对传统规范化数据模型存在的问题,梳理数据拆分的典型场景和解决方案。今天的内容,我们对这一话题进行了深入的探讨,并结合典型场景给出数据拆分的案例分析。

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

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

相关文章

6种经典的网页布局设计,你最喜欢哪个?

信息时代,我们每天都会浏览很多网页,但你有没有想过,让你停留在一个新网页的关键因素有哪些?毫无疑问,网页布局一定是关键因素之一。一个优秀的网页布局不仅可以让网站看起来更美观、更专业,还能够抓住用户…

高效记录收支明细,预设类别账户,智能统计财务脉络,轻松掌握个人财务!

收支明细管理是每位个人或企业都必须面对的财务任务,财务管理已经成为我们生活中不可或缺的一部分。如何高效记录收支明细,预设类别账户,智能统计财务脉络,轻松掌握个人财务?晨曦记账本为您提供了完美的解决方案&#…

Java 面向对象编程(OOP)

面向对象编程(Object-Oriented Programming,OOP)是Java编程语言的核心思想之一。通过OOP,Java提供了一种结构化的编程方式,使代码更易于维护和扩展。 一、类和对象 1. 类的定义 类是对象的蓝图或模板,定…

File name ‘xxxx‘ differs from already included file name ‘xxxx‘ only in casing.

一、报错信息 VSCode报错如下: File name ‘d:/object/oral-data-management/src/components/VisitLogPopup/Info.vue’ differs from already included file name ‘d:/object/oral-data-management/src/components/VisitLogPopup/INfo.vue’ only in casing. The…

【PostgreSQL17新特性之-事务级别超时参数transaction_timeout】

PostgreSQL数据库里有多个和会话相关的参数,PostgreSQL17-beta1版本新增了一个transaction_timeout参数,来限制事务的持续时间。 当前的一些和会话相关的超时参数如下 -----------------------------------------------------------------------------…

第一讲:单片机STC89C52+RA8889驱动控制彩屏(源码公开)

51单片机驱动控制彩屏系列讲座 第一讲:单片机STC89C52RA8889驱动控制彩屏(源码公开) 单片机通过SPI与RA8889进行通信,由于单片机是5V,RA8889是3.3V,故需要进行电平转换,有现成的模组TXS0108E等可以采用。…

linux开放某一个端口具体步骤

场景:当服务器防火墙不能直接关闭,但是客户端必须要访问服务器某一个端口时。 处理:对服务器端进行处理,只将该端口开放出来让客户端访问 本地使用vm安装了一个centos服务器,ip地址是 192.168.200.130。在这里充当服…

Kafka原生API使用Java代码-生产者-异步发送消息回调

文章目录 1、异步发送消息&回调1.1、pom.xml1.2、KafkaProducer1.java 1、异步发送消息&回调 回调就是接收kafka的响应 1.1、pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0&q…

Android Studio无法改变Button背景颜色解决办法

大家好&#xff0c;我是咕噜铁蛋&#xff01;今天我来和大家探讨一个在Android开发中常见但可能让初学者感到困惑的问题——如何在Android Studio中改变Button的背景颜色。这个问题看似简单&#xff0c;但实际操作中可能会遇到一些意想不到的挑战。接下来&#xff0c;我将从多个…

Facebook:社交世界的接口

在当今数字时代&#xff0c;社交媒体已经成为了人们生活中不可或缺的一部分&#xff0c;而Facebook作为其中的巨头之一&#xff0c;扮演着至关重要的角色。本文将带您深入探索Facebook这张社交世界的画卷&#xff0c;全面了解这个令人着迷的平台。 起源与历程 Facebook的故事始…

AI虚拟试穿革命:I2VEdit技术引领电商视频内容创新

在当今快速迭代的电子商务领域,用户体验与内容创新是企业竞争力的核心要素。随着AI技术的飞速进步,AI虚拟试穿已不再局限于静态图像,而是迈向了动态视频的新纪元。本文将深入解析一项革新性技术——I2VEdit,如何以其独到之处,为电商尤其是服装零售行业带来一场内容创作与产…

JVM学习-字节码指令集(二)

对象的创建与访问指令 创建指令 虽然类实例和数组都是对象&#xff0c;但Java虚拟机对类实例和数组的创建和操作使用了不同的字节码指令创建类实例指令&#xff1a;new 它接收一个操作数&#xff0c;指向常量池的索引&#xff0c;表示要创建的类型&#xff0c;执行完成后&am…

重磅发布,2024精选《制造业商业智能BI最佳实践合集 》

在数字时代&#xff0c;中国制造业正面临着前所未有的深刻变革。 商业环境的复杂性与多变性、全球化竞争的激烈程度、消费需求的快速演变&#xff0c;以及新技术的持续进步等多种因素共同推动着制造企业积极加入数字化转型的潮流。 在这个转型的过程中&#xff0c;转型的速度…

Java设计模式 _行为型模式_备忘录模式

一、备忘录模式 1、备忘录模式 备忘录模式&#xff08;Memento Pattern&#xff09;是一种行为型模式。通过保存一个对象的某个状态&#xff0c;以便在适当的时候恢复对象。 2、实现思路 &#xff08;1&#xff09;、定义记录数据的格式规范。 &#xff08;2&#xff09;、编…

pyqt Qtreeview分层控件

pyqt Qtreeview分层控件 介绍效果代码 介绍 QTreeView 是 PyQt中的一个控件&#xff0c;它用于展示分层数据&#xff0c;如目录结构、文件系统等。QTreeView 通常与模型&#xff08;如 QStandardItemModel、QFileSystemModel 或自定义模型&#xff09;一起使用&#xff0c;以管…

WAF几种代理模式详解

WAF简介 WAF的具体作用就是检测web应用中特定的应用&#xff0c;针对web应用的漏洞进行安全防护&#xff0c;阻止如SQL注入&#xff0c;XSS&#xff0c;跨脚本网站攻击等 正向代理 WAF和客户端与网络资源服务器都建立连接&#xff0c;但是WAF 的工作口具有自己的 IP 地址&…

oracle数据回显时候递归实战

太简单的两篇递归循环 orcale 在项目里递归循环实战 先看资产表T_ATOM_ASSET结构 看业务类别表T_ATOM_BUSI_CATEGORY结构 问题出现 页面显示 实际对应的归属业务分类 涉及到oracle递归实战(这里不会如何直接在atomAsset的seelct里面处理递归回显) 直接在实现层看atomAs…

zynq/zynqMP启动模式总结:FLASH+emmc启动/petalinux烧写速度最快的启动方式

因客户要求zynq开发板只有FLASH和emmc&#xff0c;然而还得在petalinux进行开发系统&#xff0c;因FLASH大小有限&#xff0c;所以没办法把内核和根文件地址全部存储到FLASH中&#xff0c;于是想配合emmc进行启动&#xff0c;但是在网上搜索的大多都是只把根文件系统放到了emmc…

Leetcode - 131双周赛

一&#xff0c;3158. 求出出现两次数字的 XOR 值 本题是一道纯模拟题&#xff0c;直接暴力。 代码如下&#xff1a; class Solution {public int duplicateNumbersXOR(int[] nums) {int ans 0;long t 0;for(int x : nums){if(((t>>x)&1) 1){ans ^ x;}else{t | (…

U-Net网络

U-Net网络 一、基本架构 各个箭头的解释&#xff1a; conv 3 * 3, ReLU&#xff1a;表示通过一个3 * 3的卷积层&#xff0c;并且该层自动附带一个非线性激活层&#xff08;ReLu&#xff09;copy and crop&#xff1a;表示进行裁剪然后再进行拼接&#xff08;在channel的维度上…