什么是分库分表?它有哪些实现类型?

假如你正在使用关系型数据库开发一款健康类系统。业务发展很好,系统有很多活跃的新老用户,这些用户会和平台的医生团队进行交互,每天可能会生成数万甚至数十万级别的业务数据。这样的话,随着数据量越来越大,系统中的某些数据表的访问就会出现瓶颈,最典型的就是用于保存用户和医生日常交流数据的健康咨询表:


虽然从理论上讲,像健康咨询表这样位于关系型数据库中的单个表可以存储的数据能够达到亿条级别,但这时候访问性能就会变得很差。业界普遍认为,诸如MySQL这样的主流数据库,单表容量在千万以下是一项最佳实践,一旦超过这个量级,就需要考虑采用其他方案。那么问题就来了,我们如何应对日益增长的数据量呢?有没有成熟的解决方案呢?

答案是肯定的,这就是我们接下来要引入的分库分表技术。所谓分库分表,你可以简单理解为:将原来独立的数据库拆分成若干数据库,将原来数据量大的单个表拆分成若干个数据表,使得单一数据库、单一数据表的数据量变得足够小,从而达到提升数据库性能的效果。有时候,我们也把分库分表统称为是一种数据分片技术,因为从概念上讲,无论是分库还是分表,都是把一定数据划分成不同的数据片,并存储在不同的目标对象中。

讲到这里,你实际上已经明确了一点,无论是分库还是分表,本质上体现的都是一种对现有数据进行拆分的思想,而这种拆分思想又有两种不同的实现策略,即垂直拆分和水平拆分:


相比水平拆分,垂直拆分相对比较容易理解和实现,所以我们先来讨论这种拆分策略。在健康类系统中,用户在查看健康咨询表数据时,位于健康咨询首页的诸如咨询编号、医生编号等基础数据的访问频率显然要比咨询详情等明细数据更高,因为用户总是先定位到基础数据,然后再选择某一个咨询记录并查看明细。基于这两种数据的不同访问特性,我们可以把健康咨询这种单表进行拆分,根据访问频次来把咨询数据分别放在两张表中,如下所示:


由此可以,垂直分表的处理方式就是将一个表按照字段分成多张表,每个表存储其中一部分字段。在实现上,我们通常会把诸如详情类的低热度数据放在一张独立的表中。

通过垂直分表能得到来一定程度的性能提升,但毕竟拆分后的数据仍然都是位于同一个数据库实例中,每个表还是会竞争同一台数据库服务器中的CPU、内存、网络IO等资源,性能的提升限制很多。基于这一考虑,在有了垂直分表之后,我们就可以进一步引入垂直分库。

让我们回到案例,针对前面介绍的场景,分表之后的健康咨询表同样还是跟健康用户表等其他数据表存放在同一台服务器中。基于垂直分库思想,这时候,我们就可以把健康咨询相关的数据表单独拆分出来,放在一个独立的数据库中,如下图所示:


上图的效果就是垂直分库。从定义上讲,垂直分库是指将表进行分类,然后分布到不同的数据库实例上。显然,在高并发场景下,垂直分库能够一定程度的提升IO访问效率和数据库连接数,并降低单机硬件资源的瓶颈。

从前面的分析中我们不难明白,垂直拆分尽管实现起来比较简单,但并不能解决单表数据量过大这一核心问题。所以,现实中我们往往需要在垂直拆分的基础上再添加水平拆分机制。例如,我们可以对健康咨询库中的健康咨询表数据按照用户编号进行取模,然后分别存储在不同的数据库中,这就是水平分库的常见做法,如下所示:


可以看到,水平分库是把同一个表的数据按一定规则拆分到不同的数据库实例中。如果采用了上图中的水平分库方案,系统复杂度就会比垂直分库要高很多,因为我们就不得不面临一个问题,即如何知道目标数据位于哪一个数据库中呢?这就需要引入路由规则的概念。像上图中根据“用户编号以3取模”就是一条路由规则。

那么,我们如何来设计并实现这些路由规则呢?业界也存在一系列路由算法,常见的包括范围限定算法、预定义算法以及前面介绍的取模算法:


参照水平分库的思路,我们也可以对用户库中的用户表进行水平拆分,效果如下所示。也就是说,水平分表是在同一个数据库内,把同一个表的数据按一定规则拆到多个表中。


到现在为止,我们已经把分库分表的基本概念梳理了一遍。你会发现这些概念理解起来并不是很复杂,但如何实现这些概念呢?你可以自己从零开始打造一套分库分表的实现工具,但显然并没有看上去那么简单,而我也不推荐你重复造轮子。幸好,目前业界已经存在一批分库分表的实现方案,主要分成客户端类分库分表和代理服务类分库分表两大类,接下去我也来介绍一下。


所谓客户端类分库分表,相当于在使用数据库的客户端应用程序中就完成了数据分片的实现。针对这种方案,因为没有独立的服务器组件,所以结构上比较简单。在Java世界中,通常做法会把客户端分片相关的处理逻辑单独抽离出来封装成一个独立的工具包,从而避免业务代码和分库分表逻辑过于耦合。而这个独立工具包的构建方法通常就是覆写现有的JDBC规范,这样,业务开发人员还是使用与JDBC规范完全兼容的一套API来操作数据库,但这套API的背后却自动完成了分库分表操作,效果如下:


这种解决方案的优势在于分库分表操作对于业务而言是完全透明的。这样,普通业务开发人员只需要理解JDBC规范就可以自行实现分库分表,开发难度以及代码维护成本得到降低。

另一方面,代理服务类分库分表的解决方案也比较明确,顾名思义,就是采用了代理机制,也就是说在应用层和数据库层之间添加一个代理层。有了代理层之后,对内我们就可以把分片规则集中维护在这个代理层中,对外则同样提供与JDBC兼容的API给到应用层,其效果如下所示:


显然,代理服务器分库分表方案的优点在于解放了业务开发人员对分库分表规则的管理工作,而缺点就是添加了一层代理层,一方面会因为新增了一层网络传输而对性能产生一定的影响;另一方面,通常也需要专门的运维人员来确保代理服务器本身的稳定性。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java项目:基于SSM框架实现的游戏攻略网站系统分前后台【ssm+B/S架构+源码+数据库+毕业论文+任务书】

一、项目简介 本项目是一套基于SSM框架实现的游戏攻略网站系统 包含:项目源码、数据库脚本等,该项目附带全部源码可作为毕设使用。 项目都经过严格调试,eclipse或者idea 确保可以运行! 该系统功能完善、界面美观、操作简单、功能…

静态方法与实例方法的区别

静态方法与实例方法的区别 1、静态方法(Static Methods)1.1 调用方式1.2 访问权限 2、实例方法(Instance Methods)2.1 调用方式2.2 访问权限 3、总结 💖The Begin💖点点关注,收藏不迷路&#x1…

使用 Smart-doc 记录 Spring REST API

如果您正在使用 Spring Boot 开发 RESTful API,您希望让其他开发人员尽可能容易地理解和使用您的 API。文档是必不可少的,因为它为将来的更新提供了参考,并帮助其他开发人员与您的 API 集成。很长一段时间以来,记录 REST API 的方…

用Python轻松转换Markdown文件为PDF文档

Markdown,以其简洁的语法和易于阅读的特性,成为了许多作家、开发者和学生记录思想、编写教程或撰写报告的首选格式。然而,在分享或打印这些文档时,Markdown的纯文本形式可能无法满足对版式和布局的专业需求。而将Markdown转换为PD…

模拟退火算法1——简介

模拟退火算法来源于固体退火原理,将固体加温至充分高,再让其徐徐冷却,加温时,固体内部粒子随温升变为无序状,内能增大,而徐徐冷却时粒子渐趋有序,在每个温度都达到平衡态,最后在常温…

【C++】 解决 C++ 语言报错:Stack Overflow

文章目录 引言 栈溢出(Stack Overflow)是 C 编程中常见且严重的错误之一。栈溢出通常发生在程序递归调用过深或分配过大的局部变量时,导致栈空间耗尽。栈溢出不仅会导致程序崩溃,还可能引发不可预测的行为。本文将深入探讨栈溢出…

周下载量20万的npm包---store

https://www.npmjs.com/package/store <script setup> import { onMounted } from vue import store from storeonMounted(() > {store.set(user, { name: xutongbao })let user store.get(user)console.log(user) //对象console.log(localStorage.getItem(user)) //…

各种特殊损失函数

死区损失函数 点击查看代码 import numpy as np import matplotlib.pyplot as plt# Define the parameters a 2 b 5 epsilon 0.1# Define the loss function L(x) and its derivative def L(x, a, b, epsilon):if x < a:return (x - a)**2 / (2 * epsilon)elif x > b:…

Windows编程原理-消息驱动的机制

Windows为每一个输入事件产生一个输入消息&#xff0c;如&#xff1a; 移动鼠标按键…… 从程序角度看待Windows消息处理 Windows使用一个窗口前必须&#xff1a; 填充一个结构&#xff1a;WNDCLASS注册窗口创建窗口使用窗口撤销窗口 从这个机制看&#xff0c;windows操作系统…

Java | Leetcode Java题解之第214题最短回文串

题目&#xff1a; 题解&#xff1a; class Solution {public String shortestPalindrome(String s) {int n s.length();int[] fail new int[n];Arrays.fill(fail, -1);for (int i 1; i < n; i) {int j fail[i - 1];while (j ! -1 && s.charAt(j 1) ! s.charAt…

Rural Access Index (RAI)农村通达指数

农村通达指数&#xff08;RAI&#xff09; 简介 农村通达指数&#xff08;RAI&#xff09;是全球交通领域最重要的发展指标之一。它是目前可持续发展目标中唯一一个直接衡量农村通达性的指标&#xff0c;通过评估农村人口的四季道路通达性来实现。在 2015 年作为可持续发展目…

Go语言--自定义函数

定义格式 函数构成代码执行的逻辑结构。在 Go语言中&#xff0c;兩数的基本组成为:关键字 func、函数名、参数列表、返回值、所数体和返回语句。 函数定义说明: func:函数由关键字func开始声明FuncName:函数名称&#xff0c;根据约定&#xff0c;数名首字母小写即为private…

Git 操作补充:变基

变基 在 Git 中&#xff0c;整合来自不同分支的修改&#xff0c;除了 merge&#xff0c;还有一种方法&#xff0c;变基 rebase。git rebase 命令基本是是一个自动化的 cherry-pick 命令&#xff0c;它计算出一系列的提交&#xff0c;然后在其他地方以同样的顺序一个一个的 che…

华为 eNSP 模拟器 配置RIP实例 动态路由协议

1 实验拓扑 2 配置路由器 #R1 Huawei>sys [Huawei]sysname R1 [R1]interface GigabitEthernet 0/0/0 [R1-GigabitEthernet0/0/0]ip address 192.168.1.1 255.255.255.0 [R1-GigabitEthernet0/0/0]qu [R1]rip [R1-rip-1]network 192.168.1.0 [R1-rip-1]version 2 [R1-rip-…

C++:求梯形面积

梯形面积 已知上底15厘米&#xff0c;下底25厘米&#xff0c;问梯形面积值是多少&#xff1f; #include<iostream> using namespace std; int main() {//梯形的面积公式&#xff08;上底下底&#xff09; 高 2//上底变量、下底变量int s,d,h,m;s15;d25;h 2*150 * 2/s ;…

Bootstrap 图片

Bootstrap 图片 Bootstrap 是一个流行的前端框架,它提供了一套丰富的工具和组件,用于快速开发响应式和移动优先的网页。在本文中,我们将探讨如何使用 Bootstrap 来处理和展示图片,包括图片的响应式设计、图片样式和图片布局。 响应式图片 Bootstrap 通过其栅格系统提供了…

接口自动化测试高频面试题

一、json和字典的区别&#xff1f; json就是一个文本、字符串&#xff1b;有固定的格式&#xff0c;格式长的像python字典和列表的组合&#xff1b; 以key-value的键值对形式来保存数据&#xff0c;结构清晰&#xff0c;。可以说是目前互联网项目开发中最常用的一种数据交互格…

k8s record 20240703

1. containerd 它不用于直接和开发人员互动&#xff0c;在这方面不和docker竞争 containerd的用时最短&#xff0c;性能最好。 containerd 是容器的生命周期管理&#xff0c;容器的网络管理等等&#xff0c;真正让容器运行需要runC containerd 是一个独立的容器运行时&am…

PyTorch环境配置及安装

PyTorch环境配置及安装 Step1&#xff1a;安装Anaconda 参考该链接&#xff08;视频01:30--03:00为安装教程&#xff09;&#xff1a; 【PyTorch深度学习快速入门教程&#xff08;绝对通俗易懂&#xff01;&#xff09;【小土堆】】 https://www.bilibili.com/video/BV1hE41…

AIGC在软件开发中的应用

目录 1. AIGC技术概述1.1 定义与背景1.2 发展历程 2. AIGC在软件开发中的应用2.1 代码生成2.2 错误检测与修复2.3 自动化测试 3. AIGC对开发者职业前景的影响3.1 助力与赋能开发者代码示例&#xff1a;自动化测试 3.2 技能需求转变与职业转型压力代码示例&#xff1a;AIGC辅助的…