RSS
菜单
全部文章快讯开发科技深度热点

第 31 章 字节系MySQL真题精讲

内容摘要

字节系(内容/推荐/电商/工程效率)面试的 MySQL 题偏重"工程实现与数据一致性"——不太纠结八股细节,而是追问你怎么在大规模、快速迭代的工程里把数据做对、把变更管好。本篇精选 20 道公开高频题型,覆盖大宽表、并发更新、大事务拆分、异步不丢数、SQL 审核、索引评审、监控告警、数据订正、DDL 上线流程、备份 RTO/RPO。题目均为公开面经常见类型,解析讲通用原理,不涉及任何公司未公开信息。前置知识:第 4、5、14、18、20 章;本系列示例基于 MySQL 8.0。

📖 本篇简介:字节系(内容/推荐/电商/工程效率)面试的 MySQL 题偏重"工程实现与数据一致性"——不太纠结八股细节,而是追问你怎么在大规模、快速迭代的工程里把数据做对、把变更管好。本篇精选 20 道公开高频题型,覆盖大宽表、并发更新、大事务拆分、异步不丢数、SQL 审核、索引评审、监控告警、数据订正、DDL 上线流程、备份 RTO/RPO。题目均为公开面经常见类型,解析讲通用原理,不涉及任何公司未公开信息。前置知识:第 4、5、14、18、20 章;本系列示例基于 MySQL 8.0。

目录

  • 1 本篇考情与知识地图
  • 题目 1:高并发下数据一致性怎么落地
  • 题目 2:大宽表和窄表怎么选
  • 题目 3:海量埋点数据MySQL放哪
  • 题目 4:并发更新同一行怎么减少锁竞争
  • 题目 5:为什么不推荐存储过程和触发器
  • 题目 6:大事务有什么危害怎么拆
  • 题目 7:异步化改造怎么保证不丢数据
  • 题目 8:一致性和可用性冲突怎么权衡
  • 题目 9:批量写入最佳实践
  • 题目 10:分库分表后数据怎么订正
  • 题目 11:SQL上线前审核查什么
  • 题目 12:索引设计评审怎么做
  • 题目 13:数据库监控告警体系怎么建
  • 题目 14:一次线上数据不一致怎么排查
  • 题目 15:哪些数据不该放MySQL
  • 题目 16:DDL变更上线流程怎么走
  • 题目 17:数据对账系统怎么做
  • 题目 18:高QPS下连接池参数怎么配
  • 题目 19:备份恢复RTO RPO怎么定
  • 题目 20:从技术债角度怎么看表设计
  • 速查速记
  • 常见坑与注意事项
  • 复习清单
  • 练习题

1 本篇考情与知识地图

字节系面试 MySQL 的关键词是"工程":表怎么设计、变更怎么管、不一致怎么查、上线怎么审。先建立这张工程化地图:

| 环节 | 关注点 | 工具/手段 |

|---|---|---|

| 设计 | 宽表 vs 窄表、反范式 | 评审 |

| 变更 | DDL 不锁表、可回滚 | 在线 DDL + 灰度 |

| 一致性 | 最终一致、对账 | 本地消息表 + 对账 |

| 质量 | SQL 审核、索引评审 | 上线卡点 |

| 运维 | 监控告警、备份 | 大盘 + 演练 |

主线一句话:把数据库当成需要工程化治理的资产,而不是写完 SQL 就不管。

题目 1:高并发下数据一致性怎么落地

考点

  • 本地事务边界;最终一致补偿。

参考答案

1. 单库内:用本地事务保证 ACID,别跨服务包大事务;

2. 跨服务:本地事务写业务表 + 消息表,异步投递,消费端幂等;

3. 关键路径短:事务里只做必要写,RPC 全部移出事务;

4. 对账兜底:定时对账发现并修复不一致;

5. 幂等贯穿:所有写接口带业务唯一号,重复执行不产生副作用。

-- 事务里只留必要写,本示例基于 MySQL 8.0
START TRANSACTION;
UPDATE t_account SET balance = balance - 100 WHERE uid = 1 AND balance >= 100;
INSERT INTO t_msg(msg_id, topic, status) VALUES ('m1','order.paid',0);  -- 同事务落消息
COMMIT;  -- 事务提交后由后台任务投递 m1

追问

  • 问:消息投递失败?答:消息表 status=0,后台定时扫描重投,进死信人工处理。
  • 问:消费方重复收到?答:按 msg_id 去重,幂等处理。

题目 2:大宽表和窄表怎么选

考点

  • 范式 vs 反范式;查询与写入权衡。

参考答案

1. 窄表(范式化):数据冗余小、更新一致,但查询要多表 Join;

2. 宽表(反范式):查询一次到位、免 Join,但冗余字段要同步维护;

3. 互联网多选宽表:读多写少、查询复杂,用空间换时间;

4. 代价:冗余字段更新要同步,接受短暂最终一致;

5. 原则:高频查询落宽表,核心交易数据仍范式化。

追问

  • 问:宽表冗余字段怎么同步?答:随主表更新事务内同步,或异步 binlog 同步。
  • 问:宽表会不会更新慢?答:冗余列多了更新代价大,只冗余高频展示字段。

题目 3:海量埋点数据MySQL放哪

考点

  • 存储边界;数据流。

参考答案

1. 埋点明细不进 MySQL:写 QPS 太高、分析型查询,MySQL 不擅长;

2. 链路:客户端埋点 → Kafka → 实时计算/ClickHouse → 报表;

3. MySQL 只存:需要事务、点查、状态机的核心业务数据;

4. 关联键:埋点里带业务 ID,必要时回业务库关联;

5. 成本:日志周期保留,冷热分层。

追问

  • 问:推荐特征存哪?答:特征宽表放列存/特征存储,别强塞 MySQL。
  • 问:为什么不用 MySQL 做分析?答:行存 + 事务开销,聚合扫描远不如列存。

题目 4:并发更新同一行怎么减少锁竞争

考点

  • 行锁串行;打散与合并。

参考答案

1. 缩短事务:锁内不做 RPC/重逻辑;

2. 乐观锁:冲突少用版本号,避免排队等行锁;

3. 分桶打散:热点行拆多行,请求分散;

4. 异步合并:计数类先累加内存/Redis,批量刷回;

5. 降低更新频率:别每次小改动都 update,攒批。

追问

  • 问:乐观锁失败怎么办?答:有限次重试,仍失败则让用户稍后再试。
  • 问:怎么看锁竞争?答:SHOW ENGINE INNODB STATUS 看锁等待、死锁日志。

题目 5:为什么不推荐存储过程和触发器

考点

  • 业务逻辑归属;可维护性。

参考答案

1. 业务逻辑应在应用层:易测试、易部署、跨语言通用;

2. 存储过程难调试、难版本管理、难横向扩展;

3. 触发器隐式执行:业务逻辑藏在 DB 里,出问题难排查;

4. 迁移困难:绑定特定 DB 方言,换库成本高;

5. 例外:极少数批量数据处理可用,业务逻辑仍放应用。

追问

  • 问:那复杂计算放哪?答:应用层/数仓,MySQL 只做存储和简单事务。
  • 问:触发器做审计不行吗?答:审计用 binlog 订阅更可控。

题目 6:大事务有什么危害怎么拆

考点

  • 长事务影响 undo/复制/锁。

参考答案

1. 危害:undo purge 不掉导致膨胀、锁持有久阻塞他人、主从复制延迟、回滚慢;

2. 拆分:一个大事务拆成多个小事务,中间状态可接受最终一致;

3. 异步化:非核心操作移到事务外异步;

4. 批量小批提交:大批量更新按每百行一批提交;

5. 监控:information_schema.innodb_trx 找长事务。

-- 大更新分批提交,本示例基于 MySQL 8.0
-- 每批更新100行后提交,避免一个超大事务
UPDATE t_order SET status = 2
 WHERE status = 1 AND id BETWEEN 1 AND 100 LIMIT 100;  -- 循环按主键区间分批

追问

  • 问:分批更新中间失败怎么办?答:每批独立提交,可断点续跑,不要求原子。
  • 问:长事务怎么发现?答:查 innodb_trx 的 trx_started,超过阈值告警。

题目 7:异步化改造怎么保证不丢数据

考点

  • 本地消息表/事务消息;幂等。

参考答案

1. 同步写库 + 异步发消息:用本地消息表把"写库"和"待发消息"绑在一个事务;

2. 后台投递:扫描消息表投递 MQ,成功标记;

3. 消费幂等:消费端按业务键去重;

4. 重试与死信:失败重试,超限死信 + 人工;

5. 对账:兜底发现漏发漏消费。

追问

  • 问:消息表和业务表不同库?答:那就用事务消息/最终一致方案,不能跨库本地事务。
  • 问:怎么保证消息顺序?答:单分片内有序,或按业务键路由到同一队列。

题目 8:一致性和可用性冲突怎么权衡

考点

  • CAP/BASE;业务分级。

参考答案

1. 区分业务:资金/余额要强一致, feeds/计数可最终一致;

2. 互联网倾向:可用性优先,用最终一致 + 对账补偿;

3. 强一致成本高:锁、同步等待降低吞吐;

4. 降级:故障时优先保可用,事后补偿数据;

5. 原则:能异步就不阻塞,能补偿就不强锁。

追问

  • 问:用户余额能最终一致吗?答:不能,资金类必须强一致(同事务)。
  • 问:点赞数呢?答:可以,容忍短暂不准。

题目 9:批量写入最佳实践

考点

  • 批量 insert;事务合并;顺序写。

参考答案

1. 批量 insert:INSERT ... VALUES (..),(..),(..) 一次多行,减少网络与事务开销;

2. 控制批次大小:每批几百到一千行,别过大撑爆 undo/ binlog;

3. 顺序自增主键:避免页分裂;

4. 关唯一检查/外键:导入时临时关闭,导入后恢复;

5. 本地事务合并:一批一个事务,别一行一个事务。

-- 批量写入,本示例基于 MySQL 8.0
INSERT INTO t_log(user_id, action, created_at)
VALUES (1,'login',NOW()), (2,'view',NOW()), (3,'pay',NOW());  -- 一批多行

追问

  • 问:批量导入还慢?答:load data infile 比 insert 快一个量级。
  • 问:批太大?答:binlog 巨大、主从延迟、复制风险,控制批次。

题目 10:分库分表后数据怎么订正

考点

  • 对账与修复;幂等回放。

参考答案

1. 先对账定位:以权威源为准,比对各分片差异;

2. 生成订正脚本:按差异生成补偿 SQL,dry-run 审核;

3. 幂等执行:订正 SQL 可重复执行不出错;

4. 灰度订正:先小批验证,再全量;

5. 留痕:订正记录可追溯,出问题可回滚。

追问

  • 问:订正和线上写并发?答:按业务键加锁或在低峰执行,避免订正被新写覆盖。
  • 问:怎么发现要订正?答:定时对账任务输出差异报告。

题目 11:SQL上线前审核查什么

考点

  • 上线卡点;性能与风险。

参考答案

1. 索引:where/order by 列是否有索引,全表扫描拦截;

2. 扫描行数:预估 rows 过大拦截;

3. 大事务/批量:一次更新/删除太多行拦截;

4. 禁止 SELECT *:避免拉回大字段;

5. 深分页:LIMIT 大偏移 拦截;

6. 类型匹配:防隐式转换。

追问

  • 问:审核工具怎么实现?答:解析 SQL + EXPLAIN 预跑,按规则打分。
  • 问:紧急 SQL 走绿色通道?答:要审批 + 限流,不能裸奔上线。

题目 12:索引设计评审怎么做

考点

  • 联合索引顺序;覆盖索引。

参考答案

1. 看查询模式:where/order by/group by 列;

2. 最左前缀:等值列在前、范围列在后;

3. 选择性:高选择性列优先;

4. 覆盖索引:把高频查询列都包进索引免回表;

5. 控制数量:索引太多拖慢写入,单表索引别过多。

追问

  • 问:加了索引但没用?答:EXPLAIN 看 key,多是写法失效或统计信息问题。
  • 问:联合索引列顺序?答:等值在前、范围在后、排序列兼顾。

题目 13:数据库监控告警体系怎么建

考点

  • 关键指标;分级告警。

参考答案

1. 性能:QPS、TPS、慢查询数、连接数、Threads_running;

2. 资源:CPU、内存、磁盘 IO、磁盘容量;

3. 复制:主从延迟 Seconds_Behind_Master;

4. 锁:锁等待、死锁数;

5. 分级:P0(库挂了/主从断)立即电话,P1 企业微信,P2 记录;

6. 大盘 + 值班: Grafana 大盘 + 应急预案。

追问

  • 问:告警太多没人看?答:分级 + 收敛,别把告警当噪音。
  • 问:最该盯哪几个?答:连接数、慢查询、主从延迟、磁盘容量。

题目 14:一次线上数据不一致怎么排查

考点

  • 排查路径;证据链。

参考答案

1. 复现:先确认不一致现象与范围;

2. 查日志:应用日志、binlog,看这条数据经过哪些写路径;

3. 查时序:并发写是否互相覆盖、缓存是否回填旧值;

4. 查事务:是否有事务没提交/回滚失败;

5. 定位根因:典型是双写顺序、并发覆盖、消息重复或丢失;

6. 修复 + 防复发:订正数据 + 加幂等/对账。

追问

  • 问:怎么避免并发覆盖?答:乐观锁/条件更新,别先查后改。
  • 问:缓存导致?答:延迟双删 + TTL + 对账。

题目 15:哪些数据不该放MySQL

考点

  • 存储选型边界。

参考答案

1. 海量日志/埋点:走 Kafka + 列存;

2. 全文搜索:走 ES;

3. 大对象文件:图片视频走 OSS,DB 存 URL;

4. 会话/临时计数:走 Redis;

5. 超大规模历史归档:走列存/对象存储;

6. MySQL 只留:事务强一致、结构化、需要点查/Join 的核心数据。

追问

  • 问:为什么不把文件存 BLOB?答:DB 体积膨胀、备份慢、不擅长流媒体,OSS 更便宜。
  • 问:宽表分析?答:分析走数仓,别在线库跑大聚合。

题目 16:DDL变更上线流程怎么走

考点

  • 在线 DDL;可回滚;灰度。

参考答案

1. 评估:是否锁表、耗时、影响;

2. 小表:直接 ALTER ... ALGORITHM=INPLACE, LOCK=NONE;

3. 大表:pt-online-schema-change 或 gh-ost;

4. 灰度:先从库执行、观察、再切主;

5. 备份 + 回滚预案:变更前备份,准备回滚;

6. 低峰执行:避开业务高峰。

追问

  • 问:8.0 原子 DDL 还会留残表吗?答:不会,崩溃自动回滚。
  • 问:加索引为什么要 INPLACE?答:COPY 算法会锁表复制,INPLACE 不锁写。

题目 17:数据对账系统怎么做

考点

  • 对账维度;差异处理。

参考答案

1. 对账源:以权威库/流水为准;

2. 对账维度:按天/按单比对金额、状态、计数;

3. 产出差异:自动生成差异清单;

4. 自动补偿:可自动修复的(如计数偏差)自动订正;

5. 人工处理:复杂差异进工单;

6. 周期:T+1 全量对账 + 实时准实时对账结合。

追问

  • 问:对账本身性能?答:离线跑,分批比对,别压在线库。
  • 问:差异率很高?答:先停自动补偿,人工介入查根因。

题目 18:高QPS下连接池参数怎么配

考点

  • 池大小;超时。

参考答案

1. 池别太大:过大上下文切换、DB 端连接数反而爆;

2. 公式参考:核数*2 + 有效磁盘数,通常几十到几百;

3. 等待超时:获取连接超时别太长,快速失败;

4. 空闲回收:及时回收空闲连接;

5. 监控:活跃连接、等待队列长度,满了说明瓶颈不在池。

追问

  • 问:QPS 高池就要大吗?答:不是,瓶颈通常是慢 SQL/锁,不是连接数。
  • 问:连接泄漏?答:设置 maxLifetime + 回收,监控连接数不释放。

题目 19:备份恢复RTO RPO怎么定

考点

  • RTO/RPO 含义;备份策略。

参考答案

1. RTO:可容忍的恢复时间;RPO:可容忍的数据丢失窗口;

2. 全量 + 增量/binlog:定期全量,随时 binlog 保证 RPO 接近 0;

3. 定期恢复演练:备份不演练等于没备份;

4. 异地备份:防机房级故障;

5. 按业务分级:核心库 RPO≈0(半同步+binlog),非核心放宽。

追问

  • 问:误删数据怎么恢复?答:恢复到误删前的 binlog 位点,用闪回工具反向生成 SQL。
  • 问:备份占空间?答:压缩 + 生命周期管理,老备份自动清理。

题目 20:从技术债角度怎么看表设计

考点

  • 演进视角;可维护性。

参考答案

1. 预留扩展:字段别过满,留扩展列/JSON;

2. 命名规范:统一表名字段名,降低理解成本;

3. 别过度设计:一开始不用疯狂分库分表,按需演进;

4. 迁移可控:每次变更可回滚、可灰度;

5. 文档化:表用途、关键字段、分片键写进文档;

6. 定期治理:清理无用表/索引,砍技术债。

追问

  • 问:什么时候该分库分表?答:单表千万级、单库 CPU/IO 到瓶颈,且纵向升配不划算。
  • 问:加字段是不是技术债?答:规范加字段不是债,乱加冗余才是。

速查速记

| 工程环节 | 关键动作 | 工具/手段 |

|---|---|---|

| 一致性 | 本地消息表+幂等 | 对账兜底 |

| 大事务 | 拆小、异步化 | 分批提交 |

| 批量写 | 多行 insert | load data |

| SQL上线 | 索引/扫描行数卡点 | SQL审核 |

| DDL | INPLACE/gh-ost | 灰度+备份 |

| 监控 | 慢查询/连接/延迟 | 分级告警 |

| 备份 | 全量+binlog | 定期演练 |

| 连接池 | 别贪大 | 等待超时 |

常见坑与注意事项

  • 坑 1:事务里夹 RPC——锁持有时间被网络拖长,并发雪崩,RPC 必须移出事务;
  • 坑 2:大事务不拆——undo 膨胀、主从延迟、回滚慢,按批提交;
  • 坑 3:业务逻辑写进存储过程/触发器——隐式难排查,全部收回应用层;
  • 坑 4:备份从不演练——真出事才发现备份不可用,恢复流程必须定期演练;
  • 坑 5:连接池盲目调大——DB 连接数和 CPU 调度反而恶化;
  • 注意:本篇均为公开题型与通用工程实践,不代表任何公司内部规范。

复习清单

| 题目 | 核心结论 | 易错点 |

|---|---|---|

| 一致性 | 本地消息表+对账 | 别跨服务大事务 |

| 宽表 | 读多写少反范式 | 冗余要同步 |

| 大事务 | 拆小批提交 | 别事务里RPC |

| 异步不丢 | 消息表同事务 | 消费要幂等 |

| SQL审核 | 索引+扫描行数 | 别放行全表扫 |

| DDL | INPLACE/gh-ost | 大表别裸ALTER |

| 监控 | 分级告警 | 告警别成噪音 |

| RTO/RPO | 全量+binlog | 必须演练 |

练习题

练 1:一个批量给 100 万用户发优惠券的任务用单事务执行导致主从延迟,怎么改?

<details>

<summary>参考答案</summary>

拆成小事务循环:每批 500~1000 个用户一个事务提交,批间 sleep 限速,避开高峰;进度记录可断点续跑。这样 undo/ binlog 不再暴涨,主从延迟可控,失败也只回滚当前批。

</details>

练 2:一条新 SQL 要上线,审核时你会查哪几项?

<details>

<summary>参考答案</summary>

EXPLAIN 看 type 是否 ALL、key 是否命中、rows 扫描量;检查 where/order by 列是否有索引、是否隐式转换/函数包裹、是否深分页、是否 SELECT *、是否大事务;带不上索引或扫描量过大则打回优化后再上线。

</details>

下一篇预告:第 32 章 美团系MySQL真题精讲

— 全文完 —回到顶部 ↑
下载推广海报

文章推广海报

《第 31 章 字节系MySQL真题精讲》完整推广海报
DISCUSSION

文章回复

0 条公开回复
未登录回复需要审核后公开
还没有回复,欢迎参与讨论。