日期:2026-09-27
标签:#面试 #MySQL #数据库
难度:中等
来源:牛面 MySQL 题库
答案说明:根据可访问的题目详情改写
一句话答案
分库分表是按业务或数据行分散存储与负载的手段,应在确认单库瓶颈且索引、SQL、归档等常规优化不足时考虑。
面试口语版(约 60 秒)
我会先区分垂直拆分和水平拆分:按业务域或字段拆是垂直,按用户 ID 等键把同一张表的行分布到多库多表是水平。分片的目标可能是容量、写入吞吐或隔离热点,不是“到一千万行必拆”。先用慢查询、执行计划、索引、冷热归档和读写分离确认瓶颈;如果单机写入或存储仍无法满足增长,再根据查询模式选分片键,并预先设计扩容、迁移、跨片查询和全局 ID。
原理拆解与场景
**例子:**订单按 user_id 路由到 16 个逻辑分片;用户查自己的订单只打一个分片,但后台按订单号查询要有订单号到分片的定位表,跨用户报表则走分析库或汇总表。
shard = hash(user_id) % 16
route(shard).query("SELECT * FROM orders WHERE user_id=? AND id=?", user_id, id)
垂直分库可隔离用户与订单负载,但跨库事务和 JOIN 变复杂;水平分片还引入分片键变更、热点键、分页和扩容迁移问题。社区项目 Vitess 用 Vindex 做路由并支持重分片,可作为实现参考。
关键边界与工程取舍
普通 MySQL 分区仍在同一实例内,不能等同于跨实例分库;分片不自动解决单个热门用户写热点。上面的取模路由只是示意,分片数变化会使大量键重新映射,扩容须有迁移方案。阈值看 P95/P99 延迟、CPU/IO、写入吞吐、数据增长和故障恢复时长,先做压测与迁移回滚预案。
面试官递进追问
1. 分片键选错会怎样?
参考答案: 分片键选错,首先会让高频查询无法精准路由,只能向多个分片广播,再合并排序或聚合,延迟和资源消耗随分片数增长。其次,低基数、数据倾斜或热门租户会造成容量与写入热点;频繁变更的键还要迁移记录。选键应同时检查访问条件、数据与流量分布、稳定性,以及关联数据能否同片;“用户数很多”并不代表每个用户的负载均匀。
2. 跨分片唯一约束和事务如何处理?
参考答案: 各分片的 UNIQUE 只能保护本地数据,不能自动保证跨片业务键唯一。可把同一业务键确定性路由到同一分片,或由独立的唯一键登记表原子占位,再用幂等操作完成业务写入;全局 ID 生成器只解决 ID 唯一,不等于手机号、订单外部编号也唯一。事务优先通过同片建模收敛为本地事务;必须跨片且要求原子提交时,可评估有可靠协调器与恢复机制的 XA/两阶段提交。允许最终一致时,可用本地事务加事件、幂等消费与业务补偿,但要明确中间状态和失败期限。MySQL XA 事务
3. 扩容时如何双写校验、切流与回滚?
参考答案: 我会先固定旧分片为权威写入源,建立全量快照与对应的增量日志起点,再持续复制变更。若采用应用双写,要记录事件 ID、版本和失败任务,处理重试、乱序、删除以及“旧库成功、新库失败”;两次调用成功不等于原子双写。校验时让两侧追到同一进度,按主键范围核对数量、字段和业务汇总,再灰度切读。切写前阻止旧路由继续写入、等待增量追平后切换唯一写入权威。保留旧分片和反向同步直到观察期结束;切写后回滚必须先同步新产生的写入,不能只改路由。Vitess 迁移与回切
自测
- 合上笔记,用 60 秒复述一句话结论、一个例子和一个边界。
- 完成第 3 个追问,写出你会核对的 SQL、指标或故障证据。
延伸阅读
参考资料
以 MySQL 8.4 为版本基准;官方资料核对日期:2026-09-27。