一文搞懂MySQL数据库分库分表

article/2025/8/22 2:33:50

如果数据量过大,大家一般会分库分表。分库需要注意的内容比较少,但分表需要注意的内容就多了。

工作这几年没遇过数据量特别大的业务,那些过亿的数据,因为索引设置合理,单表性能没有影响,所以实战中一直没用过分表。最近手里有个项目,预估数据量会很大,分表方案是选项之一,趁着这次机会,把分表的内容整理一下。

这次要讲的主要是水平分库分表,其它种类的分库、分表比较容易理解。后面如果不详细说明,都指水平分库分表。

1.基础知识

1.1分库分表定义

1.1.1分库

垂直分库:按照业务模块进行切分,将不同模块的表切分到不同的数据库中。

如电商系统有电商数据库,按照业务模块可以分为用户库、商品库、订单库,这些都可以当做独立数据库,不需要放到一起。好处是既能独立变更,又能隔绝相互影响。

在这里插入图片描述

1.1.2分表

垂直分表:也就是“大表拆小表”,基于列字段进行的。一般是因为表设计不合理,需要进行拆分。

如一张表存放学生、老师、课程、成绩信息,最好拆分为学生表、课程表、成绩表。

水平分表:针对数据量巨大的单张表(比如订单表),按照某种规则(RANGE,HASH取模等),切分到多张表里面去。 但是这些表还是在同一个库中,所以库级别的数据库操作还是有IO瓶颈。不建议采用。

水平分库分表:将单张表的数据切分到多个服务器上去,每个服务器具有相应的库与表,只是表中数据集合不同。 水平分库分表能够有效的缓解单机和单库的性能瓶颈和压力,突破IO、连接数、硬件资源等的瓶颈。

在这里插入图片描述

1.2分区与分片的区别

分表时经常能看到两个名词:分区和分片。这两个词都是指将大表的数据分成多块,但两者还是有本质区别的。

Sharding(分片) 的思想从分区的思想而来,但数据库分区基本上是数据对象级别的处理,比如表和索引的分区,每个子数据集上能够有不同的物理存储属性,还是单个数据库范围内的操作,而 Sharding 是能够跨数据库,甚至跨越物理机器的。

MySQL5.1提供的分区(Partition)功能确实可以实现表的分区,但是这种分区是局限在单个数据库范围里的,它不能跨越服务器的限制。
在这里插入图片描述

我们在分表的时候,一般使用的是分片方案,即数据存放在多个物理机器。

1.3分片策略

分片规则一般有如下:

1.3.1按照哈希切片

  1. mod-long:用于分区列为数值的hash分区

    分片列 id=分区列值 mod 分片数

  2. mod-long-by-hash:用于分区列为字符串的hash分区

    分片列id=hash(分区列值) mod 分片数

1.3.2按照范围切片

  1. range:建表时创建分区规则,根据分区规则就可以确定分区列的值在哪个分区上

    一般分区列为时间或者数值,如

    date_range:0: 10000001: 20000002: 30000003: 40000004: maxvalue
    

    如果分区列值为1500000,则数据放到1号分片上。

2.分库分表中间件

需要使用者感知不到这是分片表,使用时需要和正常表一样,一般需要引入中间件。

操作分片表一般有三种方式:

2.1客户端分片

所谓的客户端分片即在使用数据库的应用层直接操作分片逻辑,分片规则需要在同一个应用的多个节点间进行同步,每个应用层嵌入一个操作切片的逻辑实现。如当当网的Sharding JDBC。
在这里插入图片描述

2.2代理分片

代理分片就是在应用层和数据库层之间添加一个代理层,把分片的路由规则配置在代理层,代理层对外提供与JDBC兼容的接口给应用层,在业务实现之后,在代理层配置路由规则即可。如Mycat就是基于此种解决方案来实现的。
在这里插入图片描述

2.3支持事务的分布式数据库

支持分布式事务的框架,目前有OceanBase、TiDB框架,这些框架将可伸缩特定和分布式事务的实现包装到了分布式数据库内部实现,对使用者透明,使用者不需要直接控制这些特性,但是对事务的支持不如关系型数据,适合大数据日志系统、统计系统、查询系统、社交网站等。

2.4说明

支持事务的分布式数据库算另一种选型了,和MySQL已经没有关系。

对于客户端分片和代理分片,目前工作过的两家公司用的都是代理方式,一家用的是MyCAT,一家用的Dbatman。客户端分片方式没有接触过。这两种的区别为:
在这里插入图片描述

3.分布式事务

分片意味数据分布在多台物理机器上,引入分布式事务问题。我们将单表的数据切片后存储在多个数据库甚至是多个数据库实例中,所以依靠数据库本身的事务机制不能满足需要,这时就需要用到分布式事务来解决。关于分布式事务的相关内容可以看分布式系统与一致性协议。

这里不细讲分布式事务如何处理,后面会单独写篇文章。我们聊一下分布式事务会对操作MySQL产生什么影响。

既然知道引入了分布式事务问题,那么操作MySQL的时候,肯定不能和单表一样进行操作。不同中间件能力不一样,所以需要单独分析,我以Dbatman为例,阐述使用上的区别。

  1. 分片版本不维护自增与主键唯一,业务可自行维护唯一键
  • 意味不同分片的主键id会重复
  1. 不支持跨分片事务写,可以跨分片事务读
  • 如果确保事务操作的内容在一个分片内,就不是分布式事务,和单机行为一致
  • 一个事务涉及多个分片叫跨节点事务,单分片事务支持
  1. update和insert必须带分片列

总结一下就是操作同一个分片没影响,操作不同分片需要看中间件支持不支持。

4.是否选择分库分表

选择做分库分表,考虑的几个要素是:

  1. 空间方面:单个物理实例无法支撑数据存储需求,单台物理机无法继续通过加盘的方式扩容
  2. 主库性能:受限于单个主库的CPU/内存/磁盘IOPS的影响,接近或者达到上限后,需要拆分
  3. 容灾方面:减少单个主库宕机对于写入的影响。

针对以上3点,我们还可以多考虑一下,有没有更合适的方案

  1. 空间方面:

    • 删除历史数据清空空间
    • 修改存储模型降低对于MySQL磁盘的占用
    • 改用空间压缩比更高的存储引擎
  2. 主库性能:

    • 可以通过读写分离的方式,降低对于写库的读请求量,从而提升对于写入的支撑。
    • 优化数据写入模型,减少批量写入(削峰)
  3. 容灾方面:

    • 如果业务对于读高可用要求比较高,一般建议是做读写分离,将重要的请求路由至读库。读库数量一般会比写库多N个,在代理层面会做容灾的自动切换。
    • 从集群整体的角度看,分库分表实际上是会扩大故障率,假设单台物理机的SLA是99.99%,那么2台物理机的SLA就是99.98(约数), 10台物理机的SLA就只剩下99.90%了。平均每年的故障时间也会从52分钟提升到525分钟。所以在有些场景下,单个节点故障可能会导致代理整个不可用,从而放大故障的影响范围。

5.设计

现在项目需求为:

  1. 生成唯一码,码值为整数
  2. 码值需要批量插入数据库
  3. 对码的更新操作都是单条处理,而且对码值进行操作需要进行记录
  4. 最终数量不定,长远看数据量会很大

基于上面的需求,做如下设计:

  1. 以码值为主键,自己控制主键唯一
  2. 码表使用range进行分片,如分片范围为01亿,1亿2亿
  3. 码表的操作记录表同样使用range进行分片,分片范围和码表一致

通过这种设计能够实现需求。

但计算后发现,单表能存百亿条数据,而且索引设计比较合理,业务逻辑相对简单,无高并发请求,单表好像也可以搞。

总结

正常情况下,我们一般需要做水平分库分表,这就涉及到分布式事务,一定要考虑清楚是否能满足自己的需求、想用的SQL语句是否都能支持,考虑一下是否还有别的方案。

关于中间件的实现原理,了解的不是很深,后面有时间的话,可以学习一下。

资料

  1. MySQL 分库分表方案,总结的非常好!
  2. MySQL之分库分表(MyCAT实现)
  3. Mysql分库分表实战(一)——一文搞懂Mysql数据库分库分表
  4. MySql分表、分库、分片和分区知识
  5. 数据库分片(Sharding)与分区(Partition)的区别(转)
  6. 数据库分库分表中间件对比(很全)
  7. 分库分表中间件
  8. 分库分表:中间件方案对比
  9. XA 分布式事务原理

最后

大家如果喜欢我的文章,可以关注我的公众号(程序员麻辣烫)

我的个人博客为:https://shidawuhen.github.io/

往期文章回顾:

招聘

  1. 字节跳动|内推大放送
  2. 字节跳动|今日头条广州服务端研发工程师内推
  3. 字节跳动|抖音电商急招上海前端开发工程
  4. 字节跳动|抖音电商上海资深服务端开发工程师-交易
  5. 字节跳动|抖音电商武汉服务端(高级)开发工程师
  6. 字节跳动|飞书大客户产品经理内推咯
  7. 字节跳动|抖音电商服务端技术岗位虚位以待
  8. 字节跳动招聘专题

设计模式

  1. Go设计模式(15)-门面模式
  2. Go设计模式(14)-适配器模式
  3. Go设计模式(13)-装饰器模式
  4. Go设计模式(12)-桥接模式
  5. Go设计模式(11)-代理模式
  6. Go设计模式(10)-原型模式
  7. Go设计模式(9)-建造者模式
  8. Go设计模式(8)-抽象工厂
  9. Go设计模式(7)-工厂模式
  10. Go设计模式(6)-单例模式
  11. Go设计模式(5)-类图符号表示法
  12. Go设计模式(4)-代码编写优化
  13. Go设计模式(4)-代码编写
  14. Go设计模式(3)-设计原则
  15. Go设计模式(2)-面向对象分析与设计
  16. Go设计模式(1)-语法

语言

  1. 再也不怕获取不到Gin请求数据了
  2. 一文搞懂pprof
  3. Go工具之generate
  4. Go单例实现方案
  5. Go通道实现原理
  6. Go定时器实现原理
  7. Beego框架使用
  8. Golang源码BUG追查
  9. Gin框架简洁版
  10. Gin源码剖析

架构

  1. 分页复选设计的坑
  2. 支付接入常规问题
  3. 限流实现2
  4. 秒杀系统
  5. 分布式系统与一致性协议
  6. 微服务之服务框架和注册中心
  7. 浅谈微服务
  8. 限流实现1
  9. CDN请求过程详解
  10. 常用缓存技巧
  11. 如何高效对接第三方支付
  12. 算法总结

存储

  1. MySQL开发规范
  2. Redis实现分布式锁
  3. 事务原子性、一致性、持久性的实现原理
  4. InnoDB锁与事务简析

网络

  1. HTTP2.0基础教程
  2. HTTPS配置实战
  3. HTTPS连接过程
  4. TCP性能优化

工具

  1. GoLand实用技巧
  2. 根据mysql表自动生成go struct
  3. Markdown编辑器推荐-typora

读书笔记

  1. 《毛选》推荐
  2. 原则
  3. 资治通鉴
  4. 敏捷革命
  5. 如何锻炼自己的记忆力
  6. 简单的逻辑学-读后感
  7. 热风-读后感
  8. 论语-读后感
  9. 孙子兵法-读后感

思考

  1. 对写博客的一些思考
  2. 晚上打119的经历
  3. 为动员一切力量争取胜利而斗争
  4. 反对自由主义
  5. 实践论
  6. 评价自己的标准
  7. 2020博客总结
  8. 服务端团队假期值班方案
  9. 项目流程管理
  10. 对项目管理的一些看法
  11. 对产品经理的一些思考
  12. 关于程序员职业发展的思考
  13. 关于代码review的思考

http://chatgpt.dhexx.cn/article/b7x4S9wE.shtml

相关文章

Mysql·分库分表

Mysql分库分表 在mysql中新建数据库用以表分库分表mycat解压后配置文件参数server.xml 主要配置mycat服务的参数,比如端口号,myact用户名和密码使用的逻辑数据库等rule.xml 主要配置路由策略,主要有分片的片键,拆分的策略&#xf…

MySQL分库分表,何时分?怎么分?

👨‍🎓 博主介绍: IT邦德,江湖人称jeames007,10年DBA工作经验 中国DBA联盟(ACDU)成员,目前从事DBA及程序编程 (Web\java\Python)工作,主要服务于生产制造 现拥有 Oracle …

MySQL 分库分表实践

文章目录 一、为什么要分库分表二、库表太大产生的问题三、垂直拆分1. 垂直分库2. 垂直分表 四、水平分表1. 配置水平分表2. 测试水平分表 一、为什么要分库分表 数据库架构演变 刚开始多数项目用单机数据库就够了,随着服务器流量越来越大,面对的请求也…

MySQL如何分库分表

1. 我们为什么需要分库分表 在分库分表之前,就需要考虑为什么需要拆分。我们做一件事,肯定是有充分理由的。所以得想好分库分表的理由是什么。我们现在就从两个维度去思考它,为什么要分库?为什么要分表? 1.1 为什么要…

MYSQL 之 分库分表

分库分表 关系型数据库本身⽐较容易成为系统瓶颈,单机存储容量、连接数、处理能⼒都有限。当单表的数据量 达到2000W或100G以后,由于查询维度较多,即使添加从库、优化索引,做很多操作时性能仍下降严 重。此时就要考虑对其进⾏切分…

MySQL-分库分表详解(一)

♥️作者:小刘在C站 ♥️个人主页: 小刘主页 ♥️努力不一定有回报,但一定会有收获加油!一起努力,共赴美好人生! ♥️学习两年总结出的运维经验,以及思科模拟器全套网络实验教程。专栏&#xf…

如何实现MYSQL分库分表

我们学习了在高并发下数据库的一种优化方案:读写分离,它就是依靠主从复制的技术使得数据库实现了数据复制为多份,增强了抵抗大量并发读请求的能力,提升了数据库的查询性能的同时,也提升了数据的安全性。当某一个数据库…

MySQL 分库分表,写得太好了!

https://www.toutiao.com/a6603492496779510276/?tt_frommobile_qq&utm_campaignclient_share&timestamp1549497188&appnews_article&utm_sourcemobile_qq&iid59568063679&utm_mediumtoutiao_android&group_id6603492496779510276 Mysql分库分表…

MySQL数据库怎么进行分库分表?

▲ 点击上方“分布式实验室”关注公众号 回复“1”抽取纸质技术书 提起分库分表,对于大部分服务器开发来说,其实并不是一个新鲜的名词。随着业务的发展,我们表中的数据量会变的越来越大,字段也可能随着业务复杂度的升高而逐渐增多…

超详细的mysql分库分表方案

我们都知道,随着业务量的增长,数据量也会随之增加,这个时候就需要关注业务大表,因为大表会影响查询性能,DDL变更时间很长,影响业务的可用性,同时导致从库延迟很大,如果业务做了读写分…

Mysql分库分表实战(一)——一文搞懂Mysql数据库分库分表

由于业务需要,需要对Mysql数据库进行分库分表,故而最近一直在整理分库分表的相关知识,现手上的工作也告一段落了,抽空将自己最近的学习结果转化为博文,分享给大家,本博文打算做成一个系列的,首先…

MySQL 常用分库分表方案,都在这里了!

点击上方关注 “终端研发部” 设为“星标”,和你一起掌握更多数据库知识 转自:尜尜人物 www.cnblogs.com/littlecharacter/p/9342129.htm 一、数据库瓶颈 不管是IO瓶颈,还是CPU瓶颈,最终都会导致数据库的活跃连接数增加&#xff0…

MySQL:互联网公司常用分库分表方案汇总

作者:尜尜人物 原文:cnblogs.com/littlecharacter/p/9342129.html 本文目录 一、数据库瓶颈 IO瓶颈CPU瓶颈 二、分库分表 水平分库水平分表垂直分库垂直分表 三、分库分表工具 四、分库分表步骤 五、分库分表问题 非partition key的查询问题非partition…

MySQL分库分表

1.分库分表产生的背景 采用单数据库存储存在以下的性能瓶颈: ①IO瓶颈:热点数据太多,数据库缓存不足,产生大量磁盘IO,效率较低。请求数据太多,带宽不够,网络IO瓶颈。 ②CPU瓶颈:排…

MySQL-如何分库分表?一看就懂

一、为什么要分库分表 如果一个网站业务快速发展,那这个网站流量也会增加,数据的压力也会随之而来,比如电商系统来说双十一大促对订单数据压力很大,Tps十几万并发量,如果传统的架构(一主多从)&…

黑盒测试是用什么软件,黑盒测试的主要方法和常用的工具有什么?

黑盒测试是测试人员比较常用的一种测试方法,它主要是通过测试来检测每个功能是否都能正常使用的。黑盒测试的方法是有许多的,但有一些方法是比较主要的,比如边界值测试、等价类划分、决策表以及场景法等等。除了方法外,黑盒测试工…

黑盒测试简介和常用方法

黑盒测试简介和常用方法 定义 黑盒测试俗称功能测试,它站在用户的角度上主要是对系统或软件的界面、功能上进行测试。它把程序当成不能打开的盒子,这样不用考虑系统内部的逻辑和内部特性,只需要在程序的外部接口上检查程序是否能按照软件设计…

黑盒测试的测试方法

一般我们在做软件测试的时候,会遇到黑盒测试,白盒测试,我们今天主要说的是黑盒测试的 主要测试方法有那些。接下来就是干货了。 最常见的是 边界值 等价类 错误推测法 场景法 因果图法 判定表组成法 正交实验设计 下面是详细的解释: 前言:在期末考到来的时候复习…

黑盒测试方法一

黑盒测试是一种基于证明功能需求和用户最终需求的测试方法,设计黑盒测试用例的方法有如下8种: 等价类划分法。 边界值分析法。 因果图法。 判定表驱动测试。 场景法。 功能图法。 错误推测法。 正交试验设计法。 在实际测试工作中,往往是综合…

软件测试方法——黑盒测试九大用例设计方法

笔者:风起怨江南 出处:https://blog.csdn.net/JackMengJin 笔者原创,文章转载需注明,如果喜欢请点赞关注,感谢支持! 导读:面试和工作必备的九大黑盒软件测试方法。 目录 黑盒测试九大用例设计…