前言
单表数据量达到千万级后,索引膨胀、查询变慢、备份恢复耗时巨大,单纯索引优化无法解决。分库分表是海量数据终极扩容方案,分为分表、分库、水平拆分、垂直拆分。
一、为什么需要分库分表
- 单表千万级数据,B+Tree 索引层级变深,查询 IO 暴涨;
- 单库磁盘、CPU、连接数存在硬件上限;
- 大批量 DML 操作锁表、锁行冲突严重,并发性能差;
- 单库备份、恢复耗时极长,故障影响范围大。
二、两种拆分方案
1. 垂直拆分(分库)
按业务模块拆分数据库:用户库、订单库、商品库。 优点:业务隔离,单库压力降低; 缺点:跨库 JOIN 无法直接执行,需要代码关联。
2. 水平拆分(分表,最常用)
同一业务表按规则拆分多张子表,例如订单表拆分为 order_0 ~ order_15。 分片规则:
- 按用户 ID 取模分片;
- 按时间范围分片(按月分订单)。
三、入门落地中间件
- Sharding-JDBC:Java 客户端分库分表,无需额外服务;
- MyCat:独立中间件,代理层分片,多语言项目通用。
四、适用与不适用场景
需要分库分表
订单、日志、流水、用户行为数据,单表超 500 万行。
不需要分库分表
小型后台、管理系统,单表百万以内,索引优化即可支撑。
五、分片常见问题
- 跨分片分页、排序、聚合复杂;
- 全局唯一 ID 需要分布式 ID 生成器;
- 事务仅支持分片内本地事务,跨分片分布式事务成本高。