系列文章: 数据库
- 1 PostgreSQL是什么?世界上最先进的开源关系数据库
- 2 MongoDB是什么?文档数据库与何时选择NoSQL
✦ 快速摘要
MongoDB是以灵活JSON/BSON格式存储数据的文档数据库,适合schema频繁变化的场景。学习CRUD、聚合管道、副本集以及何时选择MongoDB而非PostgreSQL。MongoDB是全球领先的文档数据库,以灵活的JSON格式存储数据,而非像SQL那样使用固定表结构。本文解释MongoDB是什么、文档模型的工作原理、聚合管道,以及何时应选择MongoDB而非PostgreSQL。
2019
深耕自
B2B
数据解决方案
Data·AI
专业领域
需要企业数据解决方案?
自 2019 年起,AlgoData 为企业提供数据工程、分析与 AI 解决方案。
MongoDB是什么?
MongoDB是一款文档型NoSQL数据库管理系统,诞生于2009年。与SQL不同,MongoDB不将数据存储在固定的行列表中,而是以灵活的JSON文档(实际上是BSON——Binary JSON)形式存储:

JSON
1{
2 "_id": "64a1f2...",
3 "name": "Alice",
4 "email": "alice@example.com",
5 "orders": [
6 { "product": "笔记本电脑", "price": 999 },
7 { "product": "鼠标", "price": 29 }
8 ],
9 "address": {
10 "city": "河内",
11 "district": "还剑"
12 }
13}
单个用户文档内嵌了订单数据——而在SQL中这需要通过多表JOIN才能实现。
文档模型 vs 关系模型

| MongoDB(文档型) | PostgreSQL(关系型) | |
|---|---|---|
| 存储单元 | 文档(JSON) | 表中的行 |
| Schema | 灵活(不固定) | 固定(需迁移) |
| 数据关系 | 嵌入或引用 | 外键 + JOIN |
| 扩展方式 | 水平扩展(分片) | 垂直扩展(为主) |
| 事务 | 多文档(4.0+) | 完整ACID |
使用pymongo进行CRUD(Python)
Python
1from pymongo import MongoClient
2
3client = MongoClient("mongodb://localhost:27017/")
4db = client["myapp"]
5users = db["users"]
6
7# 插入
8result = users.insert_one({
9 "name": "Alice",
10 "email": "alice@example.com",
11 "active": True
12})
13print(result.inserted_id) # ObjectId('64a1f2...')
14
15# 带条件查询
16active_users = users.find({"active": True}, {"name": 1, "email": 1})
17for user in active_users:
18 print(user)
19
20# 更新
21users.update_one(
22 {"email": "alice@example.com"},
23 {"$set": {"active": False}}
24)
25
26# 删除
27users.delete_one({"email": "alice@example.com"})
使用Mongoose操作Node.js
JavaScript
1const mongoose = require('mongoose');
2await mongoose.connect('mongodb://localhost:27017/myapp');
3
4const UserSchema = new mongoose.Schema({
5 name: { type: String, required: true },
6 email: { type: String, required: true, unique: true },
7 active: { type: Boolean, default: true },
8});
9
10const User = mongoose.model('User', UserSchema);
11
12// 创建
13const user = await User.create({ name: 'Alice', email: 'alice@example.com' });
14
15// 查询
16const activeUsers = await User.find({ active: true }).select('name email');
17
18// 更新
19await User.updateOne({ email: 'alice@example.com' }, { $set: { active: false } });
聚合管道

JavaScript
1// 按月统计收入
2db.orders.aggregate([
3 { $match: { status: "completed" } },
4 { $group: {
5 _id: { $month: "$createdAt" },
6 totalRevenue: { $sum: "$amount" },
7 orderCount: { $sum: 1 }
8 }},
9 { $sort: { "_id": 1 } }
10])
副本集与高可用性

MongoDB副本集由一个主节点(Primary)和一个或多个从节点(Secondary)组成。主节点接收所有写操作;从节点持续从主节点复制数据。若主节点故障,副本集会在几秒内自动选举新的主节点——为应用提供零停机保障。
何时选择MongoDB vs PostgreSQL?
当schema不稳定、数据天然嵌套或需要快速水平扩展时,选择MongoDB。当需要复杂JOIN、完整ACID或重度报表与分析时,选择PostgreSQL。
常见问题Q&A
MongoDB以什么格式存储数据?
MongoDB以BSON(Binary JSON)格式存储数据——这是JSON的二进制扩展格式,额外支持Date、ObjectId、Binary和Decimal128等类型。通过驱动程序操作时,你看到的是普通JSON;MongoDB在存储时自动转换为BSON。
MongoDB支持事务吗?
支持,从MongoDB 4.0(2018年)起。MongoDB在副本集上支持多文档ACID事务,从4.2起在分片集群上也支持。不过MongoDB的事务开销高于PostgreSQL,只有在确实需要原子更新多个文档时才建议使用。
MongoDB中的副本集是什么?
副本集是一组存储相同数据集的MongoDB实例:一个主节点(Primary)接收所有写操作,一个或多个从节点(Secondary)持续从主节点复制数据。若主节点故障,副本集会在几秒内自动选举新的主节点——这是MongoDB基本的高可用机制。
什么是聚合管道?
聚合管道是一系列按顺序处理数据的阶段:$match(过滤文档)、$group(聚合计算,如COUNT、SUM、AVG)、$sort、$project(选择字段)、$lookup(与其他集合JOIN)。每个阶段接收上一阶段的输出,从而构建复杂的分析查询。
什么时候应该选择MongoDB而非PostgreSQL?
在以下情况选择MongoDB:schema经常变化或尚未明确(敏捷开发)、数据天然具有嵌套结构(每个品类属性不同的商品目录)、需要通过分片快速水平扩展,或团队比起SQL更熟悉JavaScript/JSON。在需要复杂JOIN、严格ACID保证或数据关系紧密时选择PostgreSQL。
MongoDB Atlas是什么?
MongoDB Atlas是云端(AWS、GCP、Azure)完全托管的MongoDB服务。Atlas自动处理备份、扩缩容、安全补丁和监控。提供免费套餐(M0:512MB),适合学习和原型开发。生产环境通常使用M10及以上的专用集群。

