分库分表策略
面试官问:"单表数据量太大怎么办?"
小张说:"分库分表。"
面试官追问:"怎么分?按用户 ID 分还是按时间分?"
小张说:"按用户 ID 分?"
面试官继续追问:"如果按时间查订单呢?比如查某个时间段的订单?"
小张开始答不上来。
分库分表是 MySQL 应对海量数据的高频方案。但这不只是一道"拆成多张表"那么简单。分片键怎么选、跨分片怎么查、数据怎么迁移——每一个都是坑。这道题能答清楚的候选人,对数据库架构的理解已经到了架构师级别。
一、分库分表的背景 🔴
1.1 单表数据量的问题
核心原因:B+ 树索引在数据量大时,索引树层数增加,查询变慢。DML 操作维护索引成本增加。
1.2 分库 vs 分表
1.3 ❌ 错误示范
候选人原话:"数据量大了就分库分表,简单。"
问题诊断:分库分表是最后的手段,引入复杂度巨大。先考虑优化索引、归档历史数据、分区表等方案。
候选人原话 2:"分库分表后就高枕无忧了。"
问题诊断:分库分表引入了一系列新问题:跨分片查询、分片键选择、分布式 ID、分片扩缩容等。
【面试官心理】 这道题我会从分片键选择切入,这是分库分表最核心的问题。如果候选人能说出不同分片键的优缺点,说明他有实战经验。
二、分片策略 🔴
2.1 哈希分片
优点:
- 数据分布均匀
- 写入分散到各个分片
缺点:
- 按范围查询困难(查 user_id 1~100 需要跨所有分片)
- 扩容困难(需要重新哈希迁移数据)
2.2 范围分片
优点:
- 按范围查询高效
- 扩缩容简单(只影响相邻分片)
缺点:
- 数据可能不均匀(热点用户集中在某个范围)
- 写入热点(新建订单集中在最后一个分片)
2.3 时间分片
优点:
- 历史数据归档简单
- 按时间查询高效
缺点:
- 最新分片写入热点
- 需要定期新建分表
三、分片键选择 🟡
3.1 常见分片键
3.2 关联查询问题
解决方案:
- 冗余字段:在 order_items 表冗余 user_id,按 user_id 分片
- 多次查询:先查 orders,再批量查 order_items
- ES:把数据同步到 ES,用 ES 做关联查询
3.3 分片键选择原则
- 高频查询优先:选择查询频率最高的字段作为分片键
- 避免跨分片:尽量让关联查询在同一个分片内完成
- 数据均匀:分片键的值分布要均匀
- 业务解耦:分片键要稳定,避免分片键变更导致大量数据迁移
四、跨分片查询 🟡
4.1 聚合查询
4.2 分页查询
4.3 分布式 ID
五、扩缩容 🟢
5.1 一致性哈希
5.2 扩容策略
- 双写策略:新旧表同时写入,迁移完成后切换
- 全量同步 + 增量同步:先全量迁移,再同步增量 binlog
- 灰度切换:逐步将流量从旧分片切换到新分片
【面试官心理】 分库分表是 MySQL 架构中的高级话题。能说清楚分片键选择、跨分片查询、扩缩容方案的候选人,说明他对分布式数据库有深入理解。