分库分表
分库方案指的是在系统设计中,为了应对 数据库性能瓶颈、存储容量限制、高并发读写 等问题,将数据根据一定规则分散存储到多个数据库实例中的方法。
一、分库方案设计原则
- 按业务维度划分:尽量让每个库内的业务相对独立,减少跨库访问。
- 均衡数据分布:确保每个库的数据量和访问压力尽量均衡。
- 可扩展性强:支持未来动态增加数据库实例。
- 支持全局唯一主键:避免主键冲突,便于数据迁移。
- 兼顾事务性与一致性:需要配合分布式事务或补偿机制。
二、常见分库策略
-
垂直分库(Vertical Sharding)
将不同业务模块的数据分别存储在不同的数据库中。
- 模块化清晰,易于维护 可按业务扩展资源
- 不解决单表数据过大问题 存在跨库事务问题
示例: • 用户服务的数据放 user_db; • 订单服务的数据放 order_db; • 支付服务的数据放 pay_db。
-
水平分库(Horizontal Sharding)
将同一个业务模块的数据,根据某个分片键(如用户 ID)拆分存储到多个库中,每个库结构相同。
数据压力分散,支持海量数据 跨库查询复杂,需要分布式事务
示例: • user_id % 4 分成 4 个库:user_db_0 ~ user_db_3
-
混合分库(垂直 + 水平)
先按业务模块垂直拆分,再对每个模块的核心大表进行水平分库。
三、分库实现方式
-
应用层实现(自定义)
在业务代码中根据规则路由到目标库。 • 优点:灵活、无中间层; • 缺点:开发复杂,维护成本高。
-
使用中间件
- ShardingSphere 开源、支持分库分表、分布式事务、读写分离
- MyCAT 类似代理的数据库中间件,支持 SQL 路由
- TDDL 阿里内部使用,开源后用于分库分表
- Vitess 谷歌开源,面向大规模数据库集群的分片方案
四、分库架构演进路径(推荐)
- 单库单表 → 数据量增加;
- 单库分表 → 单库连接数瓶颈;
- 多库分表(水平分库) → 加入读写分离;
- 分库分表 + 缓存 + 异步化 + 消息队列;
- 分布式架构(服务拆分 + 中间件治理)
五、主键策略推荐
为避免主键重复,需要使用 全局唯一 ID: • 雪花算法(Snowflake); • UUID(不推荐用于索引字段); • 数据库自动生成 + 前缀; • Redis + Lua 脚本 生成 ID; • 分布式 ID 服务(如美团 Leaf、百度 UidGenerator)
六、常见问题与应对
问题 应对策略 跨库 join 查询 拆分查询 + 应用层聚合 分布式事务 使用 TCC、SAGA、消息队列补偿 分页不准确 利用中间件支持或使用主键游标 统计类 SQL复杂 借助大数据平台(如 Flink、Spark)或缓存中间层 数据迁移与扩容 使用数据同步工具(Canal、DTS)+ 双写机制