MongoDB 和 MySQL 到底怎么选

0 阅读1分钟

新项目技术选型,leader 说"用 MongoDB 吧,灵活"。DBA 说"还是 MySQL 稳,别折腾"。两边吵了半天,最后也没吵出个结论。

核心区别

MySQLMongoDB
数据模型关系型(表 + 行 + 列)文档型(集合 + 文档)
Schema严格(每行结构必须一致)灵活(每个文档可以不同)
关联查询JOIN 很常用不支持 JOIN(用 $lookup 但性能差)
事务完整 ACID4.0 开始支持多文档事务
扩展方式垂直扩展为主天然支持水平分片
查询语言SQLMQL(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。如果确实两种数据都有,混用也行,但要接受运维复杂度上升。