MongoDB 是一种高性能、开源的 NoSQL 数据库,以其灵活的文档模型和强大的扩展性而闻名。
1.MongoDB 是什么
MongoDB 是一种 NoSQL 数据库 ,采用 文档模型 存储数据,支持灵活的 JSON 格式文档。它无需预定义表结构,能够动态调整数据结构,适合处理复杂、多变的数据类型。


1.1 MongoDB 的特点
-
灵活的文档模型:数据以 JSON 格式的文档存储,字段可以动态变化。
-
高性能:支持水平扩展,适合处理大规模数据集。
-
丰富的查询语言:提供强大的查询功能,支持聚合框架。
-
高可用性:通过副本集和分片实现高可用性和负载均衡。
1.2 MongoDB 的应用场景
传统的关系型数据库 (比如 MySQL), 在数据操作的"三高"需求以及对应的 Web 2.0 网站需求面前, 会有"力不从心"的感觉,所谓的三高需求:
高并发, 高性能, 高可用, 简称三高
- 对++数据库的高并发读写++的要求
- 对++海量数据的高效率存储和访问++的需求
- 对数据的++高扩展性和高可用性++的需求
而 MongoDB 可以应对三高需求
具体的应用场景:
- 社交场景, 使用 MongoDB 存储存储用户信息, 以及用户发表的朋友圈信息, 通过地理位置索引实现附近的人, 地点等功能.
- 游戏场景, 使用 MongoDB 存储游戏用户信息, 用户的装备, 积分等直接以内嵌文档的形式存储, 方便查询, 高效率存储和访问.
- 物流场景, 使用 MongoDB 存储订单信息, 订单状态在运送过程中会不断更新, 以 MongoDB 内嵌数组的形式来存储, 一次查询就能将订单所有的变更读取出来.
- 物联网场景, 使用 MongoDB 存储所有接入的智能设备信息, 以及设备汇报的日志信息, 并对这些信息进行多维度的分析.
- 视频直播, 使用 MongoDB 存储用户信息, 点赞互动信息等.
这些应用场景中, 数据操作方面的共同点有:
- 数据量大
- 写入操作频繁
- 价值较低的数据, 对事务性要求不高
对于这样的数据, 更适合用 MongoDB 来实现数据存储
那么我们什么时候选择 MongoDB 呢?
除了架构选型上, 除了上述三个特点之外, 还要考虑下面这些问题:
- 应用不需要事务及复杂 JOIN 支持
- 新应用, 需求会变, 数据模型无法确定, 想快速迭代开发
- 应用需要 2000 - 3000 以上的读写QPS(更高也可以)
- 应用需要 TB 甚至 PB 级别数据存储
- 应用发展迅速, 需要能快速水平扩展
- 应用要求存储的数据不丢失
- 应用需要
99.999%
高可用 - 应用需要大量的地理位置查询, 文本查询
如果上述有1个符合, 可以考虑 MongoDB, 2个及以上的符合, 选择 MongoDB 绝不会后悔.
如果用MySQL呢?
相对MySQL, 可以以更低的成本解决问题(包括学习, 开发, 运维等成本)
来源:了解非关系型数据库 NoSQL - MongoDB | 安装使用以及 CRUD 操作 - Zhenye's Blog
1.3 MongoDB 与其他数据库的区别
MongoDB 与传统的关系型数据库(如 MySQL、PostgreSQL)在多个方面存在显著区别:
数据模型
-
MongoDB:文档模型,数据以 JSON 格式存储,支持动态字段。
-
关系型数据库:表模型,数据存储在固定的表结构中,字段类型和数量固定。
存储方式
-
MongoDB:支持水平扩展(Sharding),适合处理海量数据。
-
关系型数据库:主要通过垂直扩展(增加硬件资源)提升性能。
查询语言
-
MongoDB:使用 JSON 格式的查询语言,支持动态查询。
-
关系型数据库:使用 SQL(结构化查询语言),语法严格。
事务支持
-
MongoDB :4.0+ 支持多文档事务,但性能不如关系型数据库。
-
关系型数据库:强事务支持,适用于对数据一致性要求极高的场景。
性能与扩展性
-
MongoDB:通过分片和副本集实现高可用性和水平扩展。
-
关系型数据库:扩展性有限,适合处理事务密集型应用。
MongoDB 的增删改查等基本语法
MongoDB 提供了丰富的操作语法,用于数据的增删改查。
在shell中 或者 使用 springboot 都能很方便的进行增删改查。
聚合操作
javascript
db.users.aggregate([{"$project" : {username:"$name"}}]) 投影操作 只显示 id 和 name
db.users.aggregate([{"$project" : {username:"$name",_id:0}}]) 不显示 id
db.users.aggregate([{"$project" : {username:"$name",_id:0, age:1}}]) 显示 age
db.users.aggregate([{"$match" : {age:30}}]) 匹配
db.users.aggregate([{"$match" : {age:30}}, {"$count" : "age30_count"}]) 匹配计数
db.users.aggregate([{"$group" : {_id:null, count: {$sum:1}, avg: {$avg: "$age"}}}, ])
分组聚合查询
{
_id: null,
count: 100,
avg: 33.18
}
索引操作(B+树)
MongoDB 使用 B+tree 数据结构存储索引,支持快速查找和排序。
javascript
创建索引
db.users.createIndex({ age: 1 });
age_1
db.users.createIndex({ age: -1 });
age_-1
查询索引
db.users.getIndexes();
{ v: 2, key: { _id: 1 }, name: '_id_' },
{ v: 2, key: { age: 1 }, name: 'age_1' },
{ v: 2, key: { age: -1 }, name: 'age_-1' },
{ v: 2, key: { age: 1, name: -1 }, name: 'age_1_name_-1' }
]
使用索引 分析计划
db.users.find({ age: 25 }).explain("executionStats");
winningPlan: {
stage: 'FETCH',
inputStage: {
stage: 'IXSCAN',
keyPattern: {
age: 1
},
indexName: 'age_1',
isMultiKey: false,
multiKeyPaths: {
age: []
},
isUnique: false,
isSparse: false,
isPartial: false,
indexVersion: 2,
direction: 'forward',
indexBounds: {
age: [
'[25, 25]'
]
}
}
},
集群相关知识
MongoDB 提供了强大的集群功能,用于实现高可用性和水平扩展。
具体可看:
MongoDB 数据库高级进阶 - 集群和安全 - Zhenye's Blog
副本集(Replica Set)
副本集通过主从复制实现数据的冗余和高可用性。
分片(Sharding)
分片将数据分布到多个服务器上,支持大规模数据集的存储和处理。
一般是hash sharding。