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亿以上:分库分表+分布式架构。
这样可以 保证数据库可扩展性、查询性能、事务一致性。
热门推荐
淳安自制毛豆腐的做法视频
一个抗癌药的非常规使用指南 - 贝伐珠单抗超说明书用药全解析
传统和新型食品发酵工艺
过敏反应防护全流程指南
原始股票的投资风险有哪些表现形式?这些表现形式如何进行识别和防范?
丁基橡胶的特性及应用
揭秘世界最强战斗机:全球现役五代机性能巅峰对决
住宅建筑布局形式及其特点
探索性数据分析 (EDA) 简介
团队协同的障碍:如何克服沟通不畅和信任缺失?
厦门公交,真的变了……
学士学位证书证明有用吗?法律视角下的深度解读
移民美国的利与弊:你真的了解吗?
盐酸屈他维林的药理活性与临床应用
AI 有多会一本正经地瞎编?超出你的想象!深度解析大模型的“幻觉”机制
13岁男孩反复发烧,入院一查,全家“中招”!医生:这些食物别给孩子生吃
中国金融行业人才发展报告怎么解读?
乒乓球技术革新:业余爱好者如何在直拍横打与反手推挡间做出选择
李靖丰富了中国的军事思想,他提出哪些理论?
医共体与医联体的困境与出路:如何通过创新合作实现共鸣
多方支招破解邻里漏水“恩怨局”
临沧“十大名菜”“十大特色菜”出炉 忍不住淌口水
科技创新推动农业现代化进程 提升生产效率与可持续发展
超越地平线:两栖突击的道与术
一文就够!史上最全新房装修家庭网络规划设计与组网拓扑布线指南
中国游戏,争夺全球人工智能话语权
大学英语写作技巧提升:探索高级词汇的巧妙运用
《地质灾害防灾减灾科普手册》发布为人民群众生命安全保驾护航
双氧水的作用和用途
如何处理电瓶接头氧化问题?这种处理方法是否适用于所有车型?