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 字节)构成:
- 时间戳(4 字节):创建时间;
- 机器 ID(3 字节):服务器标识;
- 进程 ID(2 字节):避免同机器多进程冲突;
- 自增序列(3 字节):同一进程内唯一。
4. MongoDB 支持的数据类型有哪些?
基础类型:字符串、数字(int/long/double)、布尔、日期、null;特殊类型:ObjectId、数组、嵌套文档、二进制数据、正则表达式。
二、原理深度题(中高级必问)
5. MongoDB 索引类型有哪些?复合索引的最左前缀原则?
- 索引类型:单字段、复合、唯一、地理空间、文本、哈希索引;
- 最左前缀:复合索引
{a:1, b:1, c:1}仅对a、a+b、a+b+c查询生效,对b、b+c查询不生效。
6. 如何优化 MongoDB 查询性能?(必考)
- 建立合适索引(避免全表扫描
COLLSCAN); - 用
projection只返回需要的字段(减少数据传输); - 分页用
skip()+limit()优化(大数据量用_id范围分页); - 避免大文档(拆分嵌套文档);
- 开启 WiredTiger 压缩,减少磁盘 IO;
- 用
explain()分析查询计划,优化慢查询。
7. MongoDB 副本集的作用?选举机制?
- 作用:高可用(故障自动转移)、读写分离(主写从读)、数据备份;
- 选举:基于 Raft 协议,奇数节点、多数派投票,优先级高 + 数据最新的从节点胜出。
8. MongoDB 分片集群的核心组件?分片键如何选择?
- 核心组件:mongos(路由)、config server(配置)、shard(分片节点);
- 分片键选择原则:
- 高频查询字段;
- 数据分布均匀(避免倾斜);
- 尽量不变更(分片键不可修改);
- 范围查询用范围分片,无范围用哈希分片。
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 写入性能优化?
- 批量写入(
bulkWrite)代替单条插入; - 关闭不必要的索引(写入时临时关闭,写完重建);
- 禁用 Journal 日志(测试环境,生产不建议);
- 调整写入关注级别(
w:1仅主节点确认,默认w:majority); - 使用内存映射,提升写入速度。
14. MongoDB 数据迁移 / 备份方案?
- 备份:
mongodump(逻辑备份)、文件系统快照(物理备份); - 恢复:
mongorestore; - 迁移:副本集同步、
mongodump + mongorestore、分片集群数据迁移工具。
15. 什么是数据倾斜?分片集群如何避免?
- 数据倾斜:某分片存储数据远多于其他分片(如分片键选择不当);
- 避免:
- 选择均匀分布的分片键(如用户 ID 哈希);
- 用标签分片手动分配数据;
- 定期迁移分片数据(balancer 自动均衡)。
四、生产排查题(实战向)
16. MongoDB 查询慢的排查思路?
- 用
db.collection.find().explain()看执行计划:是否走索引(IXSCAN)、是否全表扫描(COLLSCAN); - 检查索引是否缺失 / 失效;
- 查看慢查询日志(开启 profiling);
- 检查服务器资源(CPU / 内存 / 磁盘 IO);
- 检查文档大小(大文档导致查询耗时)。
17. 副本集主节点宕机,从节点不选举的原因?
- 集群节点数为偶数,无仲裁节点,无法形成多数派;
- 从节点优先级为 0(不可竞选主节点);
- 从节点数据落后主节点过多(Oplog 覆盖);
- 网络分区,从节点无法通信。
18. MongoDB 内存占用过高原因?
- WiredTiger 缓存设置过大(默认占物理内存 50%);
- 索引过多,内存映射文件占用高;
- 大量慢查询导致内存无法释放;
- 大文档频繁读取,缓存未淘汰。
19. 如何保证 MongoDB 数据一致性?
- 副本集同步(Oplog 重放);
- 写入关注级别设为
w:majority(多数节点确认写入); - 开启 Journal 日志(崩溃恢复);
- 关键业务用分布式事务。
20. MongoDB 不适合的场景?
- 强事务要求的核心业务(如金融支付);
- 复杂多表关联查询(MongoDB 关联查询性能差);
- 固定结构、低变更的结构化数据。
三、面试一句话核心总结(快速记忆)
- MongoDB 是文档型 NoSQL,BSON 存储,副本集(高可用)+ 分片(水平扩展);
- 索引基于 B + 树,复合索引遵循最左前缀,用
explain()优化查询; - 副本集选举靠 Raft 协议,奇数节点 + 多数派投票;
- 分片键选均匀分布字段,避免数据倾斜;
- 对比 MySQL:MongoDB 灵活易扩展,MySQL 事务强,核心业务选 MySQL。