聊一聊分库分表(是什么?怎么分?有什么坑?)

目录

为什么会分表分库?

数据分表

怎么分表?

垂直分表

好处:

缺点:

水平分表

优点:

缺点:

数据分库

怎么分库?

 水平分库

适用场景:

优点:

注意事项:

垂直分库

适用场景:

优点:

注意事项:

分库分表之后的常见问题

1.数据一致性问题:

问题描述:

解决方案:

2.数据迁移和扩容:

问题描述:

解决方案:

3.跨表查询性能:

问题描述:

解决方案:

4.分布式事务管理:

问题描述:

解决方案:

5.业务逻辑调整:

问题描述:

解决方案:


为什么会分表分库?

数据库数据会随着业务的发展而不断增多,因此数据操作,如增删改查的开销也会越来越大。

再加上物理服务器的资源有限(CPU、磁盘、内存、IO 等)。最终数据库所能承载的数据量、数据处理能力都将遭遇瓶颈。

换句话说需要合理的数据库架构来存放不断增长的数据,这个就是分库分表的设计初衷。目的就是为了缓解数据库的压力,最大限度提高数据操作的效率。

数据分表

如果单表的数据量过大,例如千万级甚至更多,那么在操作表的时候就会加大系统的开销。

每次查询会消耗数据库大量资源,如果需要多表的联合查询,这种劣势就更加明显了。

以 MySQL 为例,在插入数据的时候,会对表进行加锁,分为表锁定和行锁定。

无论是哪种锁定方式,都意味着前面一条数据在操作表或者行的时候,后面的请求都在排队,当访问量增加的时候,都会影响数据库的效率。

那么既然一定要分表,那么每张表分配多大的数据量比较合适呢?这里建议根据业务场景和实际情况具体分析。

一般来说 MySQL 数据库单表记录最好控制在 500 万条(这是个经验数字)。既然需要将数据从一个表分别存放到多个表中,那么来看看下面两种分表方式吧。

怎么分表?

垂直分表

直分表是一种将大型表按列进行拆分,将不同的列分离出来形成多个表的分表方案。通过垂直分表,可以将冗余的数据和低频使用的列从主表中分离出来,提高查询性能和减少存储空间的占用。

垂直分表通常基于数据的逻辑关系进行划分,可以按照以下方式进行:

    垂直拆分(Vertical Splitting):将原始表中的列按照功能或使用频率进行拆分,形成多个表。例如,将经常变更的列和不经常使用的列从主表中分离出来,形成一个或多个辅助表。这样可以减少主表的数据量,提高查询性能。

    冷热数据分离(Hot and Cold Data Separation):将热数据(经常被查询的数据)和冷数据(不经常被查询的数据)分离到不同的表中。将热数据存储在主表中,而将冷数据存储在单独的表中,可以提高主表的查询性能。

    稀疏列拆分(Sparse Column Splitting):对于具有大量稀疏列的表,可以将这些列拆分成一个或多个表。这种方式可以减少表的宽度,提高查询效率。

好处:
  • 提高查询性能:通过将数据划分到多个表中,减少每个表的数据量,可以加快查询速度。
  • 减少存储空间的占用:将冗余的数据和低频使用的列从主表中分离出来,可以减少存储空间的占用。
  • 简化数据管理和维护:将不同的列划分到不同的表中,可以更加灵活地进行数据管理和维护。
  • 解决业务系统层面的耦合,业务清晰。
缺点:
  • 部分表无法join,只能通过接口聚合方式解决,提升了开发的复杂度。
  • 分布式事务处理复杂。
  • 依然存在单表数据量过多的问题(需要水平切分)

水平分表

将一个表中的数据,按照关键字(例如:ID)(或取 Hash 之后)对一个具体的数字取模,得到的余数就是需要存放到的新表的位置。

用 ID 取模的分表方式分配记录

ID 分别为 01-04 的四条记录,如果分配到 3 个表中,那么对 3 取模得到的余数分别是:

  • ID:01 对 3 取模余数为 1 ,存到“表 1”。
  • ID:02 对 3 取模余数为 2 ,存到“表 2”。
  • ID:03 对 3 取模余数为 3 ,存到“表 3”。
  • ID:04 对 3 取模余数为 1 ,存到“表 1”。

当然这里只是一个例子,实际情况需要对 ID 做 Hash 之后再计算。同时还可以针对不同表所在的不同的数据库的资源来设置存储数据的多少。针对每个表所在的库的资源设置权值。

用这种方式存放数据以后,在访问具体数据的时候需要通过一个 Mapping Table 获取对应要响应的数据来自哪个数据表。目前比较流行的数据库中间件已经帮助我们实现了这部分的功能。

也就是说不用大家自己去建立这个 Mapping Table,在做查询的时候中间件帮助你实现了 Mapping Table 的功能。所以,我们这里只需要了解其实现原理就可以了。

Mapping Table 协助分表

水平拆分还有一种情况是根据数据产生的前后顺序来拆分存放。例如,主表只存放最近 2 个月的信息,其他比较老旧的信息拆分到其他的表中。通过时间来做数据区分。更有甚者是通过服务的地域来做数据区分的。

按照时间做的数据分表

需要注意的是由于分表造成一系列记录级别的问题,例如 Join 和 ID 生成,事务处理,同时存在这些表需要跨数据库的可能性:

  • Join:需要做两次查询,把两次查询的结果在应用层做合并。这种做法是最简单的,在应用层设计的时候需要考虑。
  • ID:可以使用 UUID,或者用一张表来存放生成的 Sequence,不过效率都不算高。UUID 实现起来比较方便,但是占用的空间比较大。 Sequence 表的方式节省了空间,但是所有的 ID 都依赖于单表。这里介绍一个大厂用的 Snowflake 的方式。

排序/分页:数据分配到水平的几个表中的时候,做排序和分页或者一些集合操作是不容易的。

这里根据经验介绍两种方法。对分表的数据先进行排序/分页/聚合,再进行合并。对分表的数据先进行合并再做排序/分页/聚合。

事务:存在分布式事务的可能,需要考虑补偿事务或者用 TCC(Try Confirm Cancel)协助完成。

优点:

    提高查询性能:通过将数据行分散存储在多个表中,可以提高查询性能。当查询条件涉及到分表键时,MySQL可以仅扫描相关分表,而不需要扫描整个表,从而减少了IO开销和查询时间。
    管理简化:对于大型表,水平分表可以简化数据管理。可以针对某个分表执行备份、恢复、优化等操作,而不需要对整个表进行操作。同时,也方便进行数据迁移和维护。
    分布式处理:水平分表可以支持分布式处理,允许将数据分布在多台服务器上,以提高系统的并发性和扩展性。

缺点:

    连接操作复杂:当需要跨多个分表进行连接查询时,会增加查询的复杂性。需要使用特殊的语法或合并结果集来获取完整的查询结果。
    数据一致性难以保证:在水平分表的情况下,某些操作(如跨分表事务)可能难以保证数据的一致性。
    分布式事务问题:当使用分片技术进行水平分表时,可能会涉及到分布式事务的处理,这增加了系统的复杂性和开发成本。

数据分库

每个物理数据库支持数据都是有限的,每一次的数据库请求都会产生一次数据库链接,当一个库无法支持更多访问的时候,我们会把原来的单个数据库分成多个,帮助分担压力。

怎么分库?

这里有几类分库的原则,可以根据具体场景进行选择:

  • 根据业务不同分库,这种情况都会把主营业务和其他功能分开。例如可以分为订单数据库,核算数据库,评论数据库。
  • 根据冷热数据进行分库,用数据访问频率来划分,例如:近一个月的交易数据属于高频数据,2-6 个月的交易数据属于中频数据,大于 6 个月的数据属于低频数据。
  • 根据访问数据的地域/时间范围进行分库。

水平分库

适用场景:

当单个数据库中的表过多时,可以根据业务逻辑将不同类型或功能相关的表分散到不同的数据库中,以减轻单个数据库的负担和提高数据库性能。

概念:以字段为依据,按照一定策略(hash、range等),将一个库中的数据拆分到多个库中。 结果:

  • 每个库的结构都一样;
  • 每个库的数据都不一样,没有交集;
  • 所有库的并集是全量数据;
优点:

可以根据业务需求和访问模式灵活地划分数据库,降低单个数据库的数据量和提高数据库性能。

注意事项:

不同的数据库应该存放在不同的服务器上,需要考虑数据库之间的数据一致性和跨库事务管理。

垂直分库

适用场景:

当单个数据库的性能达到瓶颈时,可以根据某种规则将数据划分到多个数据库中,每个数据库负责存储部分数据,以提高数据库的扩展性和性能。

概念:以表为依据,按照业务归属不同,将不同的表拆分到不同的库中。 结果:

  • 每个库的结构都不一样;
  • 每个库的数据也不一样,没有交集;
  • 所有库的并集是全量数据;
优点:

可以将数据分散存储在多个数据库中,有效缓解单库的性能瓶颈和压力,提高系统的并发处理能力。

注意事项:

需要考虑数据库之间的数据同步和一致性、跨库事务管理、数据路由和负载均衡等问题,选择合适的分库规则和策略。

分库分表之后的常见问题

1.数据一致性问题:

问题描述:

分库分表后,跨库、跨表的事务管理和数据同步变得复杂。需要考虑如何确保数据的一致性,以及在分布式环境下如何处理跨库事务和并发访问。

解决方案:

使用分布式事务管理框架,如Seata、XA协议等,来确保分布式事务的一致性。
采用消息队列等异步处理机制,将跨库事务拆分成本地事务,并通过消息队列来实现最终一致性。
设计合适的数据同步方案,定期或实时地将数据同步到各个库中,确保数据的一致性。

2.数据迁移和扩容:

问题描述:

随着业务的增长,可能需要对分库分表进行扩容或迁移。这涉及到数据的迁移、重新分片和负载均衡等问题,需要谨慎规划和执行,以避免数据丢失或服务中断。

解决方案:

使用分库分表中间件,如MyCAT、ShardingSphere等,可以简化数据迁移和扩容的过程,自动进行数据的重新分片和负载均衡。
采用数据迁移工具,如阿里巴巴的DataX,可以实现数据的快速迁移和同步,避免数据丢失或服务中断。

3.跨表查询性能:

问题描述:

分表后,跨表查询的性能可能会受到影响,特别是涉及到大量表的联合查询或聚合操作。需要设计合适的查询方案,尽量减少跨表查询的频率和数据量。

解决方案:

设计合适的数据模型,尽量减少跨表查询的频率和数据量,避免在大规模数据表上进行联合查询或聚合操作。
使用数据库索引来优化查询性能,确保查询语句能够有效地利用索引进行快速检索。

4.分布式事务管理:

问题描述:

分库分表后,事务管理变得更加复杂,需要考虑分布式事务的实现和一致性保证。通常会采用两阶段提交(2PC)、补偿事务(TCC)、最终一致性等分布式事务处理方案。

解决方案:

结合分布式事务管理框架,设计合适的分布式事务方案,确保事务的一致性和可靠性。
考虑使用柔性事务模型,如TCC(Try-Confirm-Cancel)模式,来处理分布式事务中的异常情况。

5.业务逻辑调整:

问题描述:

分库分表可能需要对原有的业务逻辑进行调整和优化,以适应新的数据分布和访问模式。需要重新评估业务需求,并根据实际情况做出相应的调整。

解决方案:

根据新的数据分布和访问模式,调整业务逻辑和流程,优化系统性能和用户体验。
对于需要大规模重构的业务逻辑,可以采用分阶段、分模块的方式进行调整,以降低风险和成本。

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

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

相关文章

中科方德服务器操作系统安装zabbix5.0

原文链接:中科方德服务器操作系统安装zabbix5.0 Hello,大家好啊!接着我们上一次的讨论,今天我要为大家介绍如何在已经安装好的中科方德服务器操作系统基础上,安装和配置Zabbix 5.0。Zabbix是一个开源的监控软件工具&am…

LeetCode-416. 分割等和子集【数组 动态规划】

LeetCode-416. 分割等和子集【数组 动态规划】 题目描述:解题思路一:01背包问题,动规五部曲解题思路二:0解题思路三:0 题目描述: 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分…

python爬虫 - 下载图片

文章目录 1、下载图片示例1:使用 .urlretrieve() 函数2、下载图片示例2 - 使用 open/write 函数3、下载图片示例33.1 使用 open/write 下载3.2 使用 urlretrieve下载 爬虫的本质:模拟对应的App,浏览器访问对应的地址获取到数据 1、下载图片示…

考虑预同步的虚拟同步机T型三电平逆变器并离网MATLAB仿真模型

微❤关注“电气仔推送”获得资料(专享优惠) 模型简介 三相 T 型三电平逆变器电路如图所示,逆变器主回路由三个单相 T 型逆变器组成。 直流侧输入电压为 UPV,直流侧中点电位 O 设为零电位,交流侧输出侧是三相三线制连…

4.双向循环链表的模拟实现

1.双向链表的实现 1.1双向链表节点的结构声明 typedef int LTDataType;typedef struct ListNode {struct ListNode* prev; // 指向该节点的前一个节点struct ListNode* next; // 指向该节点的后一个节点LTDataType data; // 该节点中存储的数据 }LTNode; // 将这…

Linux内核errno-base.h源码分析

上次写过一个博客,主要关于内核错误相关的源码分析(链接),最近突然发现上次的分析不完善,因此本次完善相关分析。 Linux内核中经常见到一些返回值,如-12,比如下面是我遇到过的一个截图&#xff…

【Java面试题】MySQL上篇(索引)

文章目录 索引1.索引的分类?2.B树和B树的区别?2.1B树2.2B树 3.为什么使用索引会加快查询?4.创建索引的注意点?5.索引在哪些情况下会失效?6.聚簇索引和非聚簇索引的区别?7.回表查询是什么?8.什么…

阿里云租用服务器GPU配置报价单_1年_一个月_1小时价格表

阿里云GPU服务器租用价格表包括包年包月价格、一个小时收费以及学生GPU服务器租用费用,阿里云GPU计算卡包括NVIDIA V100计算卡、T4计算卡、A10计算卡和A100计算卡,GPU云服务器gn6i可享受3折优惠,阿里云服务器网aliyunfuwuqi.com分享阿里云GPU…

电脑磁盘空间不足?学会这几招,轻松释放磁盘空间

随着科技的飞速发展,电脑已成为我们日常生活中不可或缺的一部分。无论是工作、学习还是娱乐,我们都需要依赖电脑来完成。然而,随着电脑使用时间的增长,磁盘空间不足的问题也逐渐浮现。当磁盘空间不足时,不仅会影响电脑…

2023年金融贷款骗局套路之一

源地址:2023年金融贷款骗局套路之一_预防网贷套路_计算机技术网 随着无卡消费的日夜流行,三年疫情出现,钱难寻,难找的尴尬境地,贷款骗局也出现不少。今天我们讲讲最近很流行的贷款骗局之一中的一种贷款骗局。 在平常…

第40篇:有限状态机<三>

Q:本期我们介绍有限状态机的应用之一:摩尔状态机“1101”序列检测器。 A:当检测到序列1101时,状态机输出为1。定义s_0为初始状态(即没有检测到1输入的状态),摩尔状态机的输出仅取决于现态&…

基于SpringBoot+Vue的个性化推荐电商平台(源码+文档+部署+讲解)

一.系统概述 随着网络科技的不断发展以及人们经济水平的逐步提高,网络技术如今已成为人们生活中不可缺少的一部分,而信息管理系统是通过计算机技术,针对用户需求开发与设计,该技术尤其在各行业领域发挥了巨大的作用,有…

数学建模-Matlab中randperm函数及其双重进阶版

1.randperm函数的用法 (1)这种用法就是参数只有一个数字,代表的含义就是随机排列之后打印输出; 我们举例的数字是4,就会把1到4这4个数字随机打乱之后随机输出,每次运行结果都不一样 所有可能的情况是n的…

UI自动化测试案例

备注:本文为博主原创文章,未经博主允许禁止转载。如有问题,欢迎指正。 个人笔记(整理不易,有帮助,收藏+点赞+评论,爱你们!!!你的支持是我写作的动力) 笔记目录:笔记本~笔记目录_airtest和selenium那个好用-CSDN博客 个人随笔:工作总结随笔_8、以前工作中都接触过哪…

鸿蒙南向开发:【智能烟感】

样例简介 智能烟感系统通过实时监测环境中烟雾浓度,当烟雾浓度超标时,及时向用户发出警报。在连接网络后,配合数字管家应用,用户可以远程配置智能烟感系统的报警阈值,远程接收智能烟感系统报警信息。实现对危险及时报…

Java区域基层卫生云联his系统源码 医院信息管理系统源码

基于云计算的医疗卫生信息系统(cloud-based healthcare informationsystem,简称“云 HIS”)是基于云计算技术,将医院信息系统、电子病历系统、实验室信息系统、公共卫生等系统横向集成的系统,为医疗机构信息化建设提供标准化、信息化、协同化…

003Node.js创建第一个web服务

如果用PHP来编写后端代码,需要用Apache或者Nginx的服务器,来处理客户的请求响应。对于Node.js时,不仅实现了应用,同时还实现了整个HTTP服务器. 安装 Node Snippets插件(编程自带提示) console.log(你好nodejs); //表…

代理模式:控制对象访问的智能方式

在面向对象的软件开发中,代理模式是一种结构型设计模式,它为其他对象提供一个代理或占位符以控制对这个对象的访问。代理模式在实现权限控制、延迟初始化和远程对象访问等方面非常有用。本文将详细介绍代理模式的定义、实现、应用场景以及优缺点&#xf…

【进阶篇】二、实现Java Agent的静态加载和动态加载

文章目录 1、Java Agent2、两种加载模式静态加载模式动态加载模式 3、静态加载模式实现4、动态加载的实现 1、Java Agent 通过Java Agent,生成一种特殊的jar包(一种工具),业务程序可以主动去调用jar包里的方法。比如下面这个有打…