MySQL 分库分表详细介绍
创作时间:
作者:
@小白创作中心
MySQL 分库分表详细介绍
引用
CSDN
1.
https://m.blog.csdn.net/weixin_45428910/article/details/145722600
随着业务数据量的增长,单库单表的数据库架构往往难以满足性能和容量的需求。本文将详细介绍MySQL分库分表的技术方案,包括分库分表的原因、方式、策略、实现方法以及数据一致性保证等多个方面,帮助读者掌握这一重要的数据库扩展技术。
一、为什么要分库分表?
当业务数据量增长到 单库单表 难以承载的程度时,会出现:
- 查询性能下降(索引树变大,查询变慢)。
- 写入性能瓶颈(锁冲突严重)。
- 存储容量受限(单表数据量超限)。
- 数据库单点故障风险。
解决方案
分库分表(Sharding)是一种 数据库水平扩展(Scale Out)方案,将数据拆分到多个数据库或数据表中,以提升系统吞吐能力和可扩展性。
二、分库分表的两种方式
1.分表(Sharding Table):
适用于单表数据量过大(如亿级别)。
数据拆分到多个表,仍然在 同一个数据库 中。
索引变小,查询性能提升。
2.分库分表(Sharding Database + Table):
适用于单库压力过大,主从同步瓶颈。
数据拆分到多个数据库和表,解决存储和并发问题。
适合分布式架构(但事务处理变复杂)。
三、分库分表的常见策略
1. 取模(HASH 取模)
- 方案:
数据库数:N
表数:M
分片算法:
库编号 = hash(主键) % N
表编号 = hash(主键) % M
- 示例(假设 4 库 8 表):
用户 ID 12345
数据库 = 12345 % 4 = 1
表 = 12345 % 8 = 5
数据落入 db_1.user_5 - 优点:
数据分布均匀,查询性能稳定。 - 缺点:
扩容困难,如 N=4,扩展到 8,数据需要 重新分配(导致数据迁移复杂)。
2. 范围(RANGE 分片)
- 方案:
按时间、ID 号段拆分:
用户ID 1-1,000,000 → db_1
用户ID 1,000,001-2,000,000 → db_2
- 示例(按时间分表,每月一个表):
CREATE TABLE orders_202401 (...);
CREATE TABLE orders_202402 (...);
- 优点:
数据分布直观,易管理。
支持按时间清理历史数据(如定期归档旧表)。 - 缺点:
热点数据集中(如最新数据查询压力大)。
不同表数据量不均衡(老表访问少,新表访问多)。
3. 按业务分库(垂直拆分 Vertical Sharding)
方案:
不同业务拆分到不同数据库,如:
用户数据 → user_db
订单数据 → order_db
日志数据 → log_db
- 优点:
业务隔离,减少互相影响。
单表数据量小,性能更稳定。 - 缺点:
跨库 JOIN 受限,需要 应用层聚合 。
某些库压力仍然可能过大(如订单库)。
4. 一致性哈希(Consistent Hashing)
方案:
采用 一致性哈希环,动态增加/删除节点时 减少数据迁移。
常用于 分布式缓存+数据库 组合架构。
示例(4 个库,新增第 5 个库时,仅部分数据重新分配):
- 原始:
hash(数据) -> db_1, db_2, db_3, db_4 - 新增 db_5:
仅 db_4 需要迁移部分数据到 db_5 - 优点:
动态扩容友好,数据迁移量小。 - 缺点:
实现较复杂,通常结合 一致性哈希中间件(如 Redis、ES)。
四、如何实现分库分表
1. 手动分库分表(应用层控制)
示例(Java 代码实现 Hash 分库分表)
public class ShardingUtil {
private static final int DB_COUNT = 4;
private static final int TABLE_COUNT = 8;
public static String getDatabase(String userId) {
int dbIndex = userId.hashCode() % DB_COUNT;
return "db_" + dbIndex;
}
public static String getTable(String userId) {
int tableIndex = userId.hashCode() % TABLE_COUNT;
return "user_" + tableIndex;
}
public static void main(String[] args) {
String userId = "12345";
System.out.println("Database: " + getDatabase(userId));
System.out.println("Table: " + getTable(userId));
}
}
2. 使用 ShardingSphere 进行自动分库分表
ShardingSphere 是 Apache 开源的数据库分库分表中间件,支持 读写分离 + 分库分表。
ShardingSphere 配置示例
spring:
shardingsphere:
datasource:
names: db_0, db_1
db_0:
url: jdbc:mysql://localhost:3306/db_0
username: root
password: password
db_1:
url: jdbc:mysql://localhost:3306/db_1
username: root
password: password
rules:
sharding:
tables:
user:
actual-data-nodes: db_$->{0..1}.user_$->{0..3}
table-strategy:
standard:
sharding-column: id
sharding-algorithm-name: user-inline
sharding-algorithms:
user-inline:
type: INLINE
props:
algorithm-expression: user_$->{id % 4}
五、如何保证分库分表的数据一致性
1. 事务管理
- 分库后本地事务(Single DB Transaction) 仍然有效。
- 跨库事务(Distributed Transaction) 需要使用 XA 事务 或 TCC 事务补偿机制。
2. 分布式 ID
- 由于 AUTO_INCREMENT 无法跨库,需要使用 分布式 ID 生成器:
- UUID(唯一但查询效率低)
- 雪花算法(Snowflake)
- MySQL 自增 ID 方案(每库步长不同)
- Redis 生成唯一 ID
六、总结
选型建议
数据量 < 5000万:单库,索引优化+分区表。
5000万 ~ 5亿:单库分表(Hash 分表)。
5亿以上:分库分表+分布式架构。
这样可以 保证数据库可扩展性、查询性能、事务一致性。
热门推荐
2025皮卡行业发展趋势预测暨第六届皮卡年度车型发布会在京召开
浅析智能合约的法律效力与签订技巧
智能教育重构未来教学场景
镜片磨花了,还可以继续使用吗?
不同焦段镜头人像摄影解析:从24mm到135mm效果分析
冷冻法治疗酒糟鼻护理方法
大便总粘马桶的原因,我们找到了
手臂发热有灼热感是怎么回事
交通事故维权指南:处理流程、赔偿主体与赔偿范围全解析
文件打开方式选错了,如何恢复?
合法有效的自书遗嘱:条件、无效情形及法律效力
富贵籽养殖全攻略:从播种到养护的完整指南
承诺的力量:如何通过诚信赢得信任与成功
世界气象组织最新报告:厄尔尼诺现象减弱,但影响仍在继续
国产替代之——RISC-V芯片应用前景
全国首只柯基警犬“入编”前是宠物狗,训导员:腿短不是缺点是优势
PLC扩展IO注意事项
有了当代科技加持,定陵文物被毁、兵马俑掉色的悲剧不会再上演
电脑重新启动一直转圈怎么办?分享6个小技巧,看这篇就够了
各种汽车正常胎压范围
顶级游资小鳄鱼豪掷2.73亿押注,“新宠”第一创业有何独到之处?
非谷物农产品包括什么
全球青年失业率创15年新低,但比以往更难找到体面活
制霸深水大鲤,野钓鲤鱼也有诀窍,摸透习性才好钓
美国历次降息周期,美股都怎么走?
解读电脑内存条:如何选择合适的内存提升性能?
惠州市现代职业技术学校:细微之处显大爱 让学生成为自己
销量认证:白酒市场集中度持续提高,头部企业蓬勃发展,彰显白酒产业发展韧性
解决房屋买卖纠纷中产权归属问题,李迈律师为您答疑
减肥必备!3款低热量、高纤维汤品助你冬季保暖又瘦身