SQL分表分库是应对海量数据和高并发访问的常用数据库架构手段。通过将原本集中存放的数据拆分到不同库或表中,可以降低单点负载、提升查询效率并方便后续扩容。

一、什么是分表与分库
分表是指把同一业务的一张表按某种规则拆成多张结构相同的表,分库则是把表分散到不同的数据库实例中。两者经常组合使用,统称为数据分片。
1. 垂直拆分
垂直拆分按业务维度将表拆分到不同库,例如把用户信息和订单信息分到用户库与订单库,减少单库表数量与耦合。
2. 水平拆分
水平拆分按行数据分散,例如按用户ID取模,把用户表拆成user_0到user_7共八张表,数据均匀分布。
二、常见分片策略
- 取模分片:用分片键对分片数取模,简单但扩容需迁移数据。
- 范围分片:按时间或ID区间划分,如按月分表,易产生热点。
- 一致性哈希:节点变化影响小,适合大规模分布式场景。
三、实际应用方法
1. 选择分片键
分片键应高频出现在查询条件中,且分布均匀。避免使用随机值导致跨库查询。
2. 使用中间件
可借助ShardingSphere等中间件屏蔽分片逻辑。以下为简单路由配置示例:
// 使用ShardingSphere配置按用户ID取模分库分表
public class ShardConfig {
// 分片算法:user_id % 2 决定库,% 4 决定表
public static String route(long userId) {
int db = (int)(userId % 2);
int tbl = (int)(userId % 4);
return "ds" + db + ".user_" + tbl;
}
}
3. 处理分布式事务
跨库写操作可采用最终一致性方案,如本地消息表或Seata框架,降低强一致开销。
四、注意事项
| 问题 | 说明 |
|---|---|
| 跨库查询 | 应避免多库join,可采用冗余字段或异步汇总 |
| 扩容 | 提前规划分片数,使用一致性哈希减少迁移 |
| 全局ID | 使用雪花算法或号段模式生成唯一ID |
五、示例SQL
下面展示在应用层手动路由后的插入语句示例:
-- 假设 userId=1001,路由到 ds0.user_1 INSERT INTO ds0.user_1 (id, user_name, age) VALUES (1001, '张三', 28);
合理运用SQL分表分库策略,可以让系统在数据膨胀时仍保持稳定的性能与可维护性。