MongoDB 与关系型数据库的区别
数据模型
- MongoDB 使用文档存储,每个文档采用 BSON 格式,能够嵌套结构化数组和对象,无需预先定义固定模式
- 关系型数据库采用表格结构,数据以行和列形式存储,通常需要预定义格式
查询语言
- MongoDB 使用基于 JSON 的查询语言,采用聚合管道实现复杂数据转化,查询灵活性高
- 关系型数据库使用结构化查询语言 SQL, 但复杂查询可能影响性能
扩展性
- MongoDB 天生支持水平扩展,可以跨多态服务器分布存储数据,适合大规模数据和高并发场景。
- 关系型数据库通常依赖垂直扩展,不如 MongoDB 灵活
一致性与事务
- MongoDB 在单文档操作上提供原子性,多文档事务从 V4.0 开始支持,但与关系型数据库相比仍有限。
- 关系型数据库全面支持 ACID 事务,适合对数据一致性要求极高的场景。
MongoDB 的事务
- 性能: 强一致性事务会影响数据库的性能,而 mongoDB 的设计目标是高性能。
- 数据模型: 文档型数据库的数据模型相对灵活,但同时也增加了实现事务的复杂性。
- 使用场景: MongoDB 更适合用于存储非结构化数据和高并发读写场景,这些场景对事务的要求相对较低。
- 一致性: mongoDB 为了性能采用的是最终一致性,需要一段时间才能被所有节点看到,关系型数据库是强一致性。
在设计数据模型时,仍建议尽量利用单文档操作的原子性,只有在必要时才引入跨多文档的事务。
MongoDB 的索引类型有哪些?各自的优缺点是什么?
单字段索引(single Field)
- 优点: 简单高效,适用精确匹配/排序
- 缺点: 只优化单字段查询
复合索引(Compound Index)
- 优点: 支持多字段联合查询/排序
- 缺点: 仅最左前缀生效,占用更多内存
多键索引(MultiKey)
- 优点: 自动为数组字段每个元素创建索引
- 缺点: 大规模数组影响写入性能
文本索引(Text)
- 优点: 支持全文搜索(含语言分词)
- 缺点: 仅一个文本索引/权重管理复杂
地理空间索引(Geospatial)
- 优点: 高效处理位置查询
- 缺点: 仅适用地理坐标数据
哈希索引(Hashed)
- 优点: 均匀分片支持, 快速等值查询
- 缺点: 无法范围查询
通配符索引(Wildcard)
- 优点: 动态字段查询优化
- 缺点: 索引尺寸较大
MongoDB 的查询分析计划
db.collection.find().explain("executionStats") // 执行统计
executionStats 实际执行性能指标
1 | "executionStats": { |
理想情况下 nReturned ≈ totalKeysExamined ≈ totalDocsExamined
COLLSCAN(全表扫描) vs IXSCAN(索引扫描)
▶︎ 应尽量避免出现 COLLSCAN
如何保证 MongoDB 的数据一致性?
- 写入层保障
1 | // 强一致性写入配置 |
- 读取层控制
1 | // 读取已提交的数据 |
MongoDB 核心概念
为什么选择 MongoDB 而不是关系型数据库?
- MongoDB 的文档模型更灵活,适合快速迭代的开发模式。
- 它能处理大规模数据和高并发查询,支持水平扩展。
- 适用于非结构化或半结构化数据,提供更高的开发效率。
MongoDB 的文档模型与传统的关系模型有什么区别?
- 在 MongoDB 中,数据存储为BSON 格式的文档,类似于 JSON,而关系型数据库使用表格和行。
- 文档可以嵌套,支持复杂的数据结构,而关系型数据库需要多表关联。
什么是 BSON?它与 JSON 的区别是什么?
- BSON(Binary JSON)是 JSON 的二进制表示形式,支持更多的数据类型(如日期、二进制数据)。
- BSON 比 JSON 更高效,适合存储和传输。
数据操作与查询
如何执行 CRUD 操作?
- Create:
insertOne()
或insertMany()
。 - Read:
find()
用于查询。 - Update:
updateOne()
或updateMany()
。 - Delete:
deleteOne()
或deleteMany()
。
- Create:
什么是聚合管道?如何使用它?
- 聚合管道是一系列的处理阶段(如
$match
、$group
、$sort
),用于对数据进行复杂处理。 - 示例:
- 聚合管道是一系列的处理阶段(如
1 | db.collection.aggregate([ |
- 如何优化 MongoDB 查询性能?
- 创建合适的索引,使用
explain()
分析查询计划。 - 避免全集合扫描,减少返回的数据量。
- 创建合适的索引,使用
索引与性能优化
- 什么是索引?如何在 MongoDB 中创建索引?
- 索引是数据结构,用于加速查询。
- 使用
createIndex()
创建索引,例如:
1 | db.collection.createIndex({ field: 1 }); |
什么是复合索引?它的使用场景是什么?
- 复合索引是包含多个字段的索引。
- 适用于多字段组合查询的场景,例如
{ field1: 1, field2: -1 }
。
如何监控和优化 MongoDB 的性能?
- 使用
mongostat
、mongotop
或explain("executionStats")
分析性能瓶颈。 - 优化索引、分片和查询设计。
- 使用
高可用性与集群管理
什么是复制集?它的作用是什么?
- 复制集是一组维护相同数据集的 MongoDB 实例,提供高可用性和数据冗余。
- 包括一个主节点和多个从节点。
什么是分片?它如何实现水平扩展?
- 分片是将数据分布到多个服务器上的技术,用于处理大规模数据集。
- 通过配置分片键实现数据分布。
如何管理 MongoDB 集群?
- 使用
mongos
路由器管理分片集群,使用mongod
管理复制集。 - 监控集群状态,优化分片策略。
- 使用
事务与一致性
- MongoDB 支持事务吗?如何使用?
_ MongoDB 支持多文档事务,适用于需要原子性操作的场景。
_ 示例:
1 | session.startTransaction(); |
- 如何保证 MongoDB 中的数据一致性?
- 对于复制集,使用
"majority"
读关注和写关注来确保强一致性。 - 使用事务来保证多文档操作的一致性。
- 对于复制集,使用
实践与工具
如何备份和恢复 MongoDB 数据?
- 使用
mongodump
进行备份,mongorestore
进行恢复。 - 也可以使用快照或云服务备份。
- 使用
如何监控 MongoDB 的性能?
- 使用
mongostat
、mongotop
实时监控数据库状态。 - 集成 Prometheus 和 Grafana 进行长期性能分析。
- 使用