新项目技术选型,leader 说"用 MongoDB 吧,灵活"。DBA 说"还是 MySQL 稳,别折腾"。两边吵了半天,最后也没吵出个结论。
核心区别
| MySQL | MongoDB | |
|---|---|---|
| 数据模型 | 关系型(表 + 行 + 列) | 文档型(集合 + 文档) |
| Schema | 严格(每行结构必须一致) | 灵活(每个文档可以不同) |
| 关联查询 | JOIN 很常用 | 不支持 JOIN(用 $lookup 但性能差) |
| 事务 | 完整 ACID | 4.0 开始支持多文档事务 |
| 扩展方式 | 垂直扩展为主 | 天然支持水平分片 |
| 查询语言 | SQL | MQL(MongoDB Query Language) |
| 适合场景 | 结构化数据、复杂查询、强一致性 | 灵活 schema、高写入、大数据量 |
MySQL 擅长的
-- 复杂关联查询
SELECT o.id, o.amount, u.name, p.title
FROM orders o
JOIN users u ON o.user_id = u.id
JOIN products p ON o.product_id = p.id
WHERE o.status = 'PAID'
AND o.created_at > '2026-01-01'
ORDER BY o.amount DESC
LIMIT 20;
这种多表关联 + 条件过滤 + 排序的场景,MySQL 非常擅长。换成 MongoDB 就很别扭。
MongoDB 擅长的
// 存一个结构不固定的文档
db.contents.insertOne({
type: "article",
title: "MongoDB 入门",
tags: ["database", "nosql"],
metadata: {
author: "Alice",
views: 1000,
customFields: { // 可以随意嵌套
difficulty: "easy",
estimatedTime: 30
}
},
createdAt: new Date()
})
// 另一个文档结构可以完全不同
db.contents.insertOne({
type: "video",
title: "MongoDB 视频教程",
duration: 3600,
url: "https://..."
})
Schema 灵活,适合内容类型多样、字段经常变化的场景。
什么时候选 MongoDB
- 文档/内容管理:文章、帖子、评论,字段经常变
- 用户画像/行为数据:每个用户的属性不一样
- 日志/事件流:高写入量,很少复杂查询
- 商品属性:不同品类的商品属性差异大(手机有 CPU,衣服有尺码)
- 快速原型:项目早期需求不确定,schema 经常改
什么时候选 MySQL
- 交易系统:订单、支付、账户——需要强一致性
- 权限系统:用户-角色-权限,关系模型天然适合
- 报表/BI:复杂聚合查询、多表关联
- 已有成熟 schema:需求明确,结构稳定
- 团队 SQL 经验丰富:学习成本最低
实际项目中的选择
我们项目最终选了 MySQL + MongoDB 混用:
- MySQL:用户、订单、支付、权限——核心业务数据
- MongoDB:商品详情、用户行为日志、内容管理——灵活 schema 的数据
用户服务 → MySQL
订单服务 → MySQL
支付服务 → MySQL
商品服务 → MongoDB(不同品类属性差异太大)
内容服务 → MongoDB(字段经常变)
日志服务 → MongoDB(高写入量)
MongoDB 常用操作速查
// 插入
db.users.insertOne({ name: "Alice", age: 25 })
db.users.insertMany([{ name: "Bob" }, { name: "Charlie" }])
// 查询
db.users.find({ age: { $gte: 18, $lte: 30 } })
db.users.find({ name: /alice/i }) // 正则匹配
db.users.findOne({ _id: ObjectId("...") })
// 更新
db.users.updateOne(
{ name: "Alice" },
{ $set: { age: 26 }, $inc: { loginCount: 1 } }
)
// 删除
db.users.deleteOne({ name: "Alice" })
// 聚合(类似 GROUP BY)
db.orders.aggregate([
{ $match: { status: "PAID" } },
{ $group: { _id: "$userId", total: { $sum: "$amount" } } },
{ $sort: { total: -1 } },
{ $limit: 10 }
])
// 索引
db.users.createIndex({ name: 1 })
db.users.createIndex({ name: 1, age: -1 }) // 复合索引
总结
结构化数据、复杂查询、强一致性 → MySQL。灵活 schema、高写入、文档型数据 → MongoDB。大部分项目用 MySQL 就够了,别为了"新潮"选 MongoDB。如果确实两种数据都有,混用也行,但要接受运维复杂度上升。