MongoDB 入门教程
选型:什么时候用 / 不该用 MongoDB
本教程共 50 篇 · 第 7 篇 · 更新于 2026-07-30 · 约 7 分钟阅读
MongoDBMongoDB 入门教程选型嵌入模型事务关系型对比
7. 选型:什么时候用 / 不该用 MongoDB
本节目标:客观判断你的业务该不该用 MongoDB,看清嵌入模型的优势,也看清它在强一致事务场景下的边界。
7.1 嵌入模型为什么快
MongoDB 的杀手锏是「嵌入(Embedding)」:把常一起读取的数据塞进同一个文档。
比如一个订单和它的商品明细,关系型要分两张表连查;MongoDB 可以把明细直接放进订单文档:
// 订单文档把商品明细嵌进来了,一次读取就够
{
_id: 1001,
user_id: 1,
items: [
{ product: "键盘", qty: 1, price: 199 },
{ product: "鼠标", qty: 2, price: 89 }
],
total: 377,
status: "paid"
}
这样读一次就拿到全部,不用连表,延迟低、吞吐高。这是它最舒服的场景。
Tip经验法则:数据「一起查、一起改、一起删」,就优先嵌入。数据「各自独立变化」,才考虑引用。
7.2 嵌入模型的代价
嵌入不是万能的,有几个要注意的点:
- 文档会变大。频繁往数组里追加,文档可能膨胀,触发搬迁。
- 数组过长(比如几千条)会让查询和更新变慢。
- 一份数据被多处复用(如「分类」被很多商品引用),复制多份会冗余。
Note据 MongoDB 8.3 官方文档,单个 BSON 文档上限是 16 MB。超了这个体积,就得改用 GridFS 或重新设计结构。
7.3 事务与强一致的边界
MongoDB 8.3 已经支持多文档 ACID 事务,但有个前提:事务要在副本集(Replica Set)上跑,单机(standalone)不支持。
// 事务需要会话(session),且部署必须是副本集
const session = db.getMongo().startSession();
session.startTransaction();
try {
session.getDatabase("shop").orders.insertOne({ user_id: 1, total: 377 }, { session });
session.getDatabase("shop").users.updateOne({ _id: 1 }, { $inc: { age: 0 } }, { session });
session.commitTransaction();
} catch (e) {
session.abortTransaction();
}
Warning单机上
startTransaction()会报错。做多文档强一致业务前,先确保部署了副本集,而不是单机mongod。
7.4 和关系型数据库怎么选
不谈优劣,只看匹配度:
| 你的业务特征 | 更顺手的选择 |
|---|---|
| 结构多变、嵌套多、要快速迭代 | MongoDB |
| 需要水平分片扛海量数据 | MongoDB |
| 强依赖跨表事务、复杂连表报表 | 关系型数据库 |
| 数据高度规范化、强一致优先 | 关系型数据库 |
| 混合需求(既要 JSON 灵活又要事务) | 两者结合,或 PostgreSQL 等也支持 JSON 的库 |
Tip别被「非此即彼」带节奏。不少系统用 MongoDB 存业务文档,用关系型库存账务核心,各取所长。
7.5 一张自检清单
满足下面多条,MongoDB 多半合适:
- 实体间是「一对少」或「一对多」、且多的一方不独立变化。
- 读远多于写,且读时要整块数据。
- 需要随时加字段,不想做迁移(migration)。
- 数据量会涨到单机放不下,要分片。
相反,如果你的核心逻辑就是「转账要绝对原子、不能回滚」,关系型可能更省心。选型看场景,没有银弹。