MongoDBNotes

第 30 章:面试题精讲

zjc 于 2026-01-30 发布

这是《MongoDB 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 本章整理 MongoDB 高频面试题。回答时先给结论,再讲机制,最后补充生产实践、性能边界和故障处理。

30.1 MongoDB 是什么数据库?

MongoDB 是面向文档的分布式数据库,使用 BSON 文档保存数据,集合组织文档,支持丰富索引、聚合管道、副本集、分片和事务。

加分回答:

  1. 单文档操作原子;
  2. 多文档事务可用但应短小;
  3. 副本集提供高可用;
  4. 分片提供水平扩展;
  5. Schema 灵活但仍需治理。

30.2 MongoDB 支持 ACID 吗?

支持:

  1. 单文档更新天然原子;
  2. 副本集和分片集群支持多文档 ACID 事务;
  3. 事务需要 session、副本集环境;
  4. 分片事务成本更高;
  5. 应优先设计单文档边界。

不要回答“不支持事务”,这个结论已经过时。

30.3 内嵌和引用如何选择?

内嵌适合:

  1. 一起读取;
  2. 数量有限;
  3. 更新频率低;
  4. 生命周期一致。

引用适合:

  1. 无界增长;
  2. 独立查询;
  3. 多方修改;
  4. 文档过大。

核心是按访问模式建模,而不是机械翻译关系表。

30.4 为什么要避免无界数组?

风险:

  1. 文档持续增长;
  2. 写放大;
  3. 复制延迟增加;
  4. 索引开销增加;
  5. 查询投影浪费;
  6. 接近文档大小上限。

订单流水、评论、日志应拆集合并分页。

30.5 复合索引如何设计?

遵循 ESR:

Equality -> Sort -> Range

示例:

db.orders.createIndex({
  tenant_id: 1,
  status: 1,
  created_at: -1
})

同时满足最左前缀,并让排序字段进入索引,避免内存排序。

30.6 explain 怎么看?

重点字段:

字段 判断
winningPlan.stage COLLSCAN 或 IXSCAN
keysExamined 索引扫描量
docsExamined 文档扫描量
nReturned 返回量
SORT 内存排序
executionTimeMillis 总耗时

理想情况是 nReturned 接近 keysExamined

30.7 副本集如何工作?

流程:

client write -> primary -> oplog -> secondary apply

Primary 故障后,多数投票成员选主。生产至少三个数据节点,跨故障域部署,关键写使用 majority。

30.8 什么是 oplog?

oplog 是 local 库中的固定大小集合,记录可幂等重放的变更,用于 Secondary 同步和增量恢复。

关注:

  1. oplog 窗口;
  2. 写入速率;
  3. 复制延迟;
  4. Secondary 是否可增量追赶;
  5. 初始同步时间。

30.9 读写关注如何组合?

场景 组合
支付后读 majority 写 + primary 读
报表 majority 写 + secondaryPreferred 读
用户画像 可接受延迟读
强一致读 linearizable 或 primary + majority

写关注决定确认范围,读关注决定数据级别,读偏好决定成员。

30.10 为什么会回滚?

Primary 写入后未复制到多数节点就发生故障,新 Primary 当选后,旧 Primary 恢复时会回滚这些未提交写入。

防范:

  1. majority 写关注;
  2. 监控复制延迟;
  3. 合理多数派拓扑;
  4. 处理 rollback 文件;
  5. 演练切主。

30.11 分片键如何选择?

目标:

  1. 高基数;
  2. 低频率;
  3. 写入均匀;
  4. 高频查询可定向;
  5. 单调递增热点可控;
  6. 事务跨 shard 少。

常见选择是 tenant_id + user_iddevice_id + timestampconversation_id + message_id

30.12 哈希分片和范围分片怎么选?

类型 优势 代价
哈希 写入均匀 范围查询常广播
范围 范围查询高效 递增键易热点

订单按用户查多于按时间范围扫全表时,可以考虑用户哈希或复合键。

30.13 什么时候分片?

分片信号:

  1. 单机磁盘不足;
  2. 写入超过单机能力;
  3. 工作集长期超过内存;
  4. 数据增长明确;
  5. 索引和备份时间过长。

不解决:

  1. 慢查询无索引;
  2. 单热点文档;
  3. 应用连接滥用;
  4. 磁盘临时故障。

30.14 Change Stream 的原理是什么?

基于 oplog 的可恢复事件流,支持集合、库和集群级监听,可通过 resume token 恢复。

生产要点:

  1. token 持久化;
  2. 事件幂等;
  3. 全量 + 增量;
  4. oplog 窗口足够;
  5. 消费积压监控。

30.15 WiredTiger cache 为什么重要?

常用数据和索引页保存在 cache。工作集超过 cache 会增加磁盘读、延迟波动和 evict 压力。

优化:

  1. 控制工作集;
  2. 减少无效索引;
  3. 投影;
  4. 冷热分离;
  5. 扩内存或分片。

30.16 MongoDB 为什么会出现慢查询?

常见原因:

  1. COLLSCAN;
  2. 索引选择性差;
  3. 无索引排序;
  4. 大文档返回;
  5. 聚合数据放大;
  6. cache 压力;
  7. 磁盘瓶颈;
  8. 写冲突。

排查路径是 Profiler -> explain -> 索引 -> 资源指标。

30.17 MongoDB 和 MySQL 如何选?

MongoDB 适合文档对象、灵活字段、水平分片、Change Stream 和 JSON 契约。MySQL 适合强关系、复杂事务、强约束和成熟 SQL 生态。

不要绝对化,可通过混合架构和 CDC 组合。

30.18 生产必须做哪些保障?

  1. 副本集跨故障域;
  2. 启用认证和 TLS;
  3. 最小权限;
  4. 监控复制和 cache;
  5. 慢查询治理;
  6. 索引评审;
  7. 备份恢复演练;
  8. 容量规划;
  9. 升级回滚方案;
  10. 故障演练。

本章小结

MongoDB 面试重点集中在文档建模、索引执行计划、副本集选举、oplog、一致性、分片键、事务、Change Stream 和 WiredTiger。展示生产经验的关键是说明监控、压测、备份和故障演练。

思考题

  1. 为什么单文档原子性是设计优势?
  2. 如何用 ESR 设计索引?
  3. majority 写是否等于不丢任何数据?
  4. 分片键选择错误如何补救?
  5. Change Stream 与 oplog 的关系是什么?