MongoDB 核心原理 + 高频面试题

MongoDB 是主流的文档型 NoSQL 数据库,以灵活的文档模型、高性能、易扩展著称,是 Java 后端面试中 NoSQL 模块的核心考点(重点考:存储原理、索引、副本集、分片、与 MySQL 对比、性能优化)。


一、MongoDB 核心原理(先懂原理,再背题)

1.1 核心特性

  • 文档型数据库:数据以 BSON(二进制 JSON)格式存储,支持嵌套文档、数组,无固定表结构(.schema-less);
  • 高性能:内存映射存储、索引优化、WiredTiger 存储引擎(默认)支持压缩 / 并发;
  • 高可用:副本集(Replica Set)实现主从备份、自动故障转移;
  • 水平扩展:分片集群(Sharding)支持海量数据分布式存储;
  • 原生支持分布式事务(4.0+)、地理空间索引、全文索引。

1.2 存储核心原理

(1)数据格式:BSON

  • BSON 是二进制编码的 JSON,支持更多数据类型(Date、Int64、ObjectId、Binary 等);
  • 每个文档有唯一 _id 字段(默认自动生成 ObjectId,可自定义),作为主键。

(2)核心存储引擎(面试高频)

存储引擎 特点 适用场景
WiredTiger(默认) 支持行级锁、压缩(Snappy/Zlib)、MVCC、事务 生产环境首选,高并发、大数据量
MMAPv1(废弃) 表级锁、内存映射文件 低版本兼容,已淘汰

(3)数据存储结构

  • 命名空间(Namespace)数据库名.集合名(如 test.user);
  • 数据文件:按预分配策略生成(默认 2GB 递增),避免频繁磁盘 IO;
  • 日志机制
    • Journal 日志:预写日志(WAL),默认 100ms 刷盘,崩溃后可恢复;
    • Oplog 日志:副本集数据同步日志(固定大小的循环日志)。

1.3 索引核心原理

(1)索引结构:B + 树(和 MySQL 一致)

  • 所有索引基于 B + 树构建,叶子节点存储文档地址(磁盘指针);
  • 主键 _id 默认为唯一索引,不可删除。

(2)常见索引类型(必考)

索引类型 作用 适用场景
单字段索引 单个字段的升序 / 降序索引 单条件查询(如 where name = '张三'
复合索引 多个字段组合的索引 多条件查询(如 where age > 20 and gender = '男'
唯一索引 保证字段值唯一 手机号、邮箱等唯一标识
地理空间索引 支持地理位置查询(如附近的人) LBS 应用(外卖、打车)
文本索引 支持全文检索 文章、商品标题搜索
哈希索引 按字段哈希值索引 分片集群的分片键(均匀分布数据)

(3)索引优化原则

  • 最左前缀匹配:复合索引需按查询频率排序字段;
  • 避免覆盖低基数字段(如性别、状态);
  • explain() 分析查询计划,避免全表扫描(COLLSCAN);
  • 索引不是越多越好:写入时需维护索引,增加开销。

1.4 副本集(Replica Set)原理(高可用核心)

(1)核心角色

  • 主节点(Primary):读写操作,唯一可写节点;
  • 从节点(Secondary):只读,同步主节点 Oplog 数据;
  • 仲裁节点(Arbiter):无数据,仅参与选举(可选,集群节点为偶数时用)。

(2)选举机制(Raft 协议)

  • 集群节点数为奇数(3/5/7),满足多数派选举;
  • 主节点宕机 → 从节点竞选 Leader:优先级高、数据最新(Oplog 同步完成)、获得多数投票的节点胜出;
  • 选举完成后,新主节点对外提供服务,原主节点恢复后变为从节点。

(3)数据同步

  • 主节点写入数据 → 记录 Oplog → 从节点拉取 Oplog 重放 → 数据一致;
  • 同步模式:异步同步(默认)、半同步(确保至少一个从节点同步完成再返回)。

1.5 分片集群(Sharding)原理(水平扩展核心)

(1)核心组件

  • mongos:路由节点,接收客户端请求,转发到对应分片;
  • config server:配置服务器,存储集群元数据(分片键、分片节点信息);
  • shard:分片节点(通常是副本集),存储实际数据。

(2)分片策略

  • 范围分片:按分片键范围划分(如按时间、ID 范围),易数据倾斜;
  • 哈希分片:按分片键哈希值划分,数据分布均匀,不支持范围查询优化;
  • 标签分片:自定义分片规则(如按地区映射到指定分片)。

二、MongoDB 高频面试题(分模块,直接背)

一、基础必问题(开场 90% 问)

1. MongoDB 是什么?核心特点?

MongoDB 是文档型 NoSQL 数据库,核心特点:

  • 无模式(schema-less),BSON 文档存储,灵活适配业务变更;
  • 高性能(内存映射、索引优化)、高可用(副本集)、水平扩展(分片);
  • 支持丰富索引(地理空间、文本)、分布式事务。

2. MongoDB 的 BSON 是什么?和 JSON 区别?

  • BSON 是二进制编码的 JSON,MongoDB 原生存储格式;
  • 区别:支持更多数据类型(Date、Int64、ObjectId 等)、二进制存储更高效、易解析。

3. MongoDB 的 _id 字段作用?ObjectId 构成?

  • _id 是文档唯一主键,默认自动生成 ObjectId,不可重复;
  • ObjectId(12 字节)构成:
    1. 时间戳(4 字节):创建时间;
    2. 机器 ID(3 字节):服务器标识;
    3. 进程 ID(2 字节):避免同机器多进程冲突;
    4. 自增序列(3 字节):同一进程内唯一。

4. MongoDB 支持的数据类型有哪些?

基础类型:字符串、数字(int/long/double)、布尔、日期、null;特殊类型:ObjectId、数组、嵌套文档、二进制数据、正则表达式。

二、原理深度题(中高级必问)

5. MongoDB 索引类型有哪些?复合索引的最左前缀原则?

  • 索引类型:单字段、复合、唯一、地理空间、文本、哈希索引;
  • 最左前缀:复合索引 {a:1, b:1, c:1} 仅对 aa+ba+b+c 查询生效,对 bb+c 查询不生效。

6. 如何优化 MongoDB 查询性能?(必考)

  1. 建立合适索引(避免全表扫描 COLLSCAN);
  2. projection 只返回需要的字段(减少数据传输);
  3. 分页用 skip()+limit() 优化(大数据量用 _id 范围分页);
  4. 避免大文档(拆分嵌套文档);
  5. 开启 WiredTiger 压缩,减少磁盘 IO;
  6. explain() 分析查询计划,优化慢查询。

7. MongoDB 副本集的作用?选举机制?

  • 作用:高可用(故障自动转移)、读写分离(主写从读)、数据备份;
  • 选举:基于 Raft 协议,奇数节点、多数派投票,优先级高 + 数据最新的从节点胜出。

8. MongoDB 分片集群的核心组件?分片键如何选择?

  • 核心组件:mongos(路由)、config server(配置)、shard(分片节点);
  • 分片键选择原则:
    1. 高频查询字段;
    2. 数据分布均匀(避免倾斜);
    3. 尽量不变更(分片键不可修改);
    4. 范围查询用范围分片,无范围用哈希分片。

9. MongoDB 的事务支持?和 MySQL 事务区别?

  • MongoDB 4.0+ 支持副本集事务,4.4+ 支持分片集群事务;
  • 区别:
    • MySQL:ACID 完全支持,锁粒度细(行级);
    • MongoDB:仅支持单文档事务(默认),多文档事务需显式开启,性能略低于 MySQL,适合非核心业务。

10. Journal 日志和 Oplog 日志区别?

  • Journal:预写日志(WAL),用于崩溃恢复,保障数据持久化;
  • Oplog:副本集同步日志,固定大小循环日志,记录主节点所有写操作。

三、实战 & 对比题(生产经验)

11. MongoDB vs MySQL(最常问)

特性 MongoDB MySQL
数据模型 文档型(无模式) 关系型(固定表结构)
事务 支持多文档 / 分布式事务(弱) 强 ACID 事务
索引 B + 树、地理空间、文本索引 B + 树、全文索引(需插件)
扩展 水平扩展(分片)易 水平扩展复杂(分库分表)
适用场景 非结构化 / 半结构化数据(日志、用户画像、LBS) 结构化数据(订单、支付、核心业务)

12. Spring Data MongoDB 常用注解?

  • @Document:标记实体类对应 MongoDB 集合;
  • @Id:指定主键字段(对应 _id);
  • @Field:指定字段名(映射集合字段);
  • @Indexed:标记索引字段;
  • @CompoundIndex:标记复合索引。

13. MongoDB 写入性能优化?

  1. 批量写入(bulkWrite)代替单条插入;
  2. 关闭不必要的索引(写入时临时关闭,写完重建);
  3. 禁用 Journal 日志(测试环境,生产不建议);
  4. 调整写入关注级别(w:1 仅主节点确认,默认 w:majority);
  5. 使用内存映射,提升写入速度。

14. MongoDB 数据迁移 / 备份方案?

  • 备份:mongodump(逻辑备份)、文件系统快照(物理备份);
  • 恢复:mongorestore
  • 迁移:副本集同步、mongodump + mongorestore、分片集群数据迁移工具。

15. 什么是数据倾斜?分片集群如何避免?

  • 数据倾斜:某分片存储数据远多于其他分片(如分片键选择不当);
  • 避免:
    1. 选择均匀分布的分片键(如用户 ID 哈希);
    2. 用标签分片手动分配数据;
    3. 定期迁移分片数据(balancer 自动均衡)。

四、生产排查题(实战向)

16. MongoDB 查询慢的排查思路?

  1. db.collection.find().explain() 看执行计划:是否走索引(IXSCAN)、是否全表扫描(COLLSCAN);
  2. 检查索引是否缺失 / 失效;
  3. 查看慢查询日志(开启 profiling);
  4. 检查服务器资源(CPU / 内存 / 磁盘 IO);
  5. 检查文档大小(大文档导致查询耗时)。

17. 副本集主节点宕机,从节点不选举的原因?

  1. 集群节点数为偶数,无仲裁节点,无法形成多数派;
  2. 从节点优先级为 0(不可竞选主节点);
  3. 从节点数据落后主节点过多(Oplog 覆盖);
  4. 网络分区,从节点无法通信。

18. MongoDB 内存占用过高原因?

  1. WiredTiger 缓存设置过大(默认占物理内存 50%);
  2. 索引过多,内存映射文件占用高;
  3. 大量慢查询导致内存无法释放;
  4. 大文档频繁读取,缓存未淘汰。

19. 如何保证 MongoDB 数据一致性?

  1. 副本集同步(Oplog 重放);
  2. 写入关注级别设为 w:majority(多数节点确认写入);
  3. 开启 Journal 日志(崩溃恢复);
  4. 关键业务用分布式事务。

20. MongoDB 不适合的场景?

  1. 强事务要求的核心业务(如金融支付);
  2. 复杂多表关联查询(MongoDB 关联查询性能差);
  3. 固定结构、低变更的结构化数据。

三、面试一句话核心总结(快速记忆)

  1. MongoDB 是文档型 NoSQL,BSON 存储,副本集(高可用)+ 分片(水平扩展);
  2. 索引基于 B + 树,复合索引遵循最左前缀,用 explain() 优化查询;
  3. 副本集选举靠 Raft 协议,奇数节点 + 多数派投票;
  4. 分片键选均匀分布字段,避免数据倾斜;
  5. 对比 MySQL:MongoDB 灵活易扩展,MySQL 事务强,核心业务选 MySQL。
相关推荐
darling3312 小时前
mysql 自动备份以及远程传输脚本,异地备份
android·数据库·mysql·adb
Bruk.Liu2 小时前
(LangChain实战12):LangChain中的新型Chain之create_sql_query_chain
数据库·人工智能·sql·langchain
世界尽头与你2 小时前
MySQL InnoDB的 MVCC 实现机制
数据库·mysql
青树寒鸦2 小时前
wsl的docker备份mongo和迁移
运维·mongodb·docker·容器
你刷碗2 小时前
基于S32K144 CESc生成随机数
android·java·数据库
松涛和鸣2 小时前
70、IMX6ULL LED驱动实战
linux·数据库·驱动开发·postgresql·sqlserver
世界尽头与你3 小时前
详解 MySQL 数据库索引实现机制 - B 树和 B + 树
数据库·mysql·索引
德彪稳坐倒骑驴3 小时前
MySQL Oracle面试题
数据库·mysql·oracle
数据知道3 小时前
PostgreSQL 核心原理:什么场景下开启 JIT 能提升性能?(JIT 编译)
数据库·postgresql