大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
何时用 Mongo vs SQL
这一课你将能做到
- 对照场景矩阵,说出至少 3 类「更偏 MySQL」与 3 类「更偏 MongoDB」的具体理由
- 用本站架构解释:为何
cf_track留在 MySQL,而做题日志 / 评论适合进 MongoDB - 在团队评审中给出「混合持久化」建议,并明确双写风险与单一权威源原则
为什么要学
工具课容易学成「都会一点」;工程上真正值钱的是选型能辩护。面试官问「你们为什么用 MongoDB」时,背得出 CRUD API 没用,答得出「数据形状 + 一致性 + 团队资产」三层理由才有用。
本站的技术决策摆在这里:权威数据(课程、用户、做题进度、订单)在 MySQL——schema.sql、JPA 实体、迁移脚本都是已投入的资产;MongoDB 承接文档型扩展集合。本课把这背后的判断逻辑系统化,让你能在自己的项目里做出并捍卫同类决策。
人话:不是谁更高级,而是「数据长什么样、怎么变、怎么查、一致性要多强」决定谁更合适;外加团队与运维的真实成本。
先建立图像
按职责分层选型:
核心业务 OLTP(用户、课程目录、做题进度、订单)
→ MySQL:事务、JOIN、约束、成熟生态
文档 / 日志 / 多变结构(做题日志、评论、审计、配置树)
→ MongoDB:内嵌、灵活字段、追加写、聚合统计
热点加速 / 会话 / 限流
→ Redis:内存读写,挡在数据库前面
(Nginx 统一入口 → Spring Boot 编排三者)
| 场景 | 更常见选择 | 理由 |
|---|---|---|
| 结构化 OLTP、多表 JOIN | MySQL | SQL 成熟、约束完备、团队熟悉 |
| 灵活 schema、嵌套 JSON | MongoDB | 免 ALTER、数组内嵌自然 |
| 复杂报表、窗口函数 | MySQL / PG | 分析 SQL 生态强 |
| 高写入日志、行为流水 | MongoDB | 追加友好、TTL 过期、聚合内置 |
| 强一致金融账本 | MySQL | ACID 与对账习惯成熟 |
| 单对象整读(带子结构) | MongoDB | 一次读齐,免多次 JOIN |
跟着做
步骤 1:写出本站「权威路径」一句话
打开笔记写:「Nginx → Spring Boot → MySQL(cf_track 等)为权威主路径;MongoDB 不替换 spring.datasource,只承接扩展集合。」对照仓库 application.yml,确认数据源主配置仍是 MySQL。
步骤 2:为「课时评论」做双方案草稿
MySQL 版(纸上画表):
cf_comment(id, track_slug, user_id, body, created_at, ...)
加 @ 提及还要 mention 关联表
展示作者昵称要 JOIN 用户表或冗余快照列
Mongo 版(直接能跑):
db.comments.insertOne({
trackSlug: "mongodb-essentials",
body: "聚合管道讲得很清楚",
author: { userId: "u_1002", displayName: "学习者A" }, // 快照
mentions: ["u_1001"],
createdAt: ISODate("2026-03-02T08:00:00Z")
})
对比结论写进笔记:Mongo 把作者快照与提及数组收进同一文档,读接口一次拿齐;MySQL 版赢在跨评论复杂 JOIN 报表与严格约束。
步骤 3:为「支付订单」做反向练习
尝试用 Mongo 文档表达订单:行项目可以内嵌,但写完要问自己四个问题——库存扣减谁保证?支付状态机跨单据怎么办?对账怎么跑?出问题回滚到哪一步?
答案指向:能存 ≠ 该当唯一真相。强一致账本留在 MySQL,这半页纸就是你在评审里否决「把订单迁 Mongo」提案的论据。
步骤 4:标出混合架构的红线
同一实体(如 Track 标题)
✗ 同时以 MySQL 与 Mongo 为权威并双写——无分布式事务保证,必然漂移
✓ 单一权威源(MySQL);另一侧只做只读投影或异步快照(需队列 + 对账 + 可重建)
步骤 5:扫官方映射表补术语
打开 SQL to MongoDB Mapping,挑 5 个术语抄进笔记:INSERT→insertOne、UPDATE→updateOne、GROUP BY→$group、LEFT JOIN→$lookup、PRIMARY KEY→_id。面试口头互译要零延迟。
步骤 6:写 150 字「给新同事的说明」
主题:为什么本站学 MongoDB 却不改主库。必须包含:权威数据在哪、练习库叫什么、哪类集合适合 Mongo、双写为什么禁止。写不出第 4 点就重读步骤 4。
讲清楚要点
- 数据形状是第一判据:嵌套、数组、字段演进快 → 文档;多实体强关联、要 JOIN 与约束 → 关系表。
- 一致性需求是硬约束:涉及钱、库存、对账的场景优先成熟 ACID 生态;Mongo 多文档事务要副本集环境,且周边工具链仍在追赶。
- 读写模式第二判据:单对象整读、追加为主、按范围聚合 → Mongo 顺手;跨实体复杂查询报表 → SQL 强项。
- 团队与运维成本必须计入:多一套库 = 多一套备份、监控、安全与招聘成本,「都会一点」不等于该同时上两套生产库。
- 双写是最大陷阱:无对账的双写必然漂移;跨库联动走事件驱动 + 最终一致,且消费端必须可重建。
- MySQL JSON 列是中间选项:表内少量半结构化字段可用;整库文档负载(多集合、数组索引、聚合)就该上 Mongo。
- 学完本课的可验证产出:能拒绝一个错误的迁移提案,也能为一个正确的引入提案辩护——这是选型课的「完成」标准。
你可能会懵的地方
-
Mongo 不是也有事务了吗?为什么账本还坚持 MySQL? 能做 ≠ 生态齐。外键约束、存储过程、成熟报表、DBA 运维经验、对账工具链都在关系库一侧;事务还要副本集环境。换库省下的 schema 灵活性,抵不上重建这套生态的风险。
-
MySQL 8 有 JSON 列,还要 MongoDB 吗? JSON 列适合「表中附带半结构化字段」的低频场景;当文档型负载成为主战场(多集合、数组查询、聚合统计、TTL 清理),Mongo 的整套引擎都是为它设计的。
-
「先全用 Mongo 以后再迁」可行吗? 原型期可以,权威域上线前必须有迁移计划与一致性评审。本站的选择是:权威域从第一天就放 MySQL,避免中途换轮子。
-
混合架构是不是过度设计? 出现明确文档型负载(日志量、字段演进频率、聚合需求)才引入第二存储。本课矩阵是判断题,不是「必须两条腿走路」的口号。
-
Redis 和这个话题什么关系? Redis 解决「快」(缓存、会话、限流),不解决「怎么存业务数据」。三者各司其职的架构图,面试画出来就是加分项。
错法对照
| 错法 | 问题 | 正解 |
|---|---|---|
| 「新项目默认上 Mongo」 | 忽略关联与事务需求 | 先画数据形状与一致性清单再定 |
把 cf_track 迁 Mongo「图现代」 | 打断主路径、废弃既有资产 | MySQL 不动,Mongo 做扩展集合 |
| 评论塞进 track 行内 JSON 无限涨 | 行膨胀、难索引、难分页 | 独立 comments 集合 / 独立表 |
| 两库同时改同一字段且无对账 | 永久不一致 | 单一权威源;跨库走事件 |
| 用「Mongo 也有事务」否定 MySQL 选型 | 忽略生态与运维成本 | 事务只是选型维度之一 |
| 学完 Mongo 就轻视 SQL | 技能残缺 | SQL 仍是本站主路径与面试主战场 |
卡点急救
- 说不清某实体该放哪边:按四问走——数据形状(嵌套?演进?)、写模式(追加还是改账?)、查模式(单对象整读还是跨实体 JOIN?)、一致性(强一致还是要最终一致即可)。四问写完,答案自己浮出来。
- 面试官追问「Mongo 事务不是也成熟了吗」:承认 4.0+ 多文档事务存在(需副本集),然后立即转向「生态与运维成本」:外键、报表、对账、团队经验——展示你考虑的是全局成本而非单点功能。
- 团队里有人坚持双写:给两个替代方案——只读投影(异步事件刷新 + 可重建脚本)或定时快照;并要求上线前做不一致演练,双写提案通常在演练环节自我瓦解。
面试常问
-
你们项目为什么选 MongoDB?什么时候不会选它? 选型三段答:数据形状(类 JSON、嵌套数组、字段随版本演进)、写入模式(日志类追加、吞吐高)、查询模式(单对象整读 + 聚合统计)。反例:强一致账本、复杂多表 JOIN 报表、依赖外键约束的数据继续用 MySQL。本站实践:权威数据 MySQL,做题日志与评论走 Mongo。
-
谈谈 MongoDB 的事务支持,它适合账本吗? 单文档操作天然原子;4.0 起支持多文档事务、4.2 扩展到分片集群,但要求副本集环境,且生态(约束、报表、对账)不及关系库成熟。结论:轻量多文档场景可用,金融级账本仍优先 MySQL——答「有事务所以随便用」暴露理解不深。
-
什么是混合持久化(Polyglot Persistence)?风险是什么? 按数据特征让不同存储各司其职(本站:MySQL 权威 + Mongo 文档扩展 + Redis 缓存)。核心风险:多存储间的一致性——必须单一权威源,跨库走事件最终一致并保证可重建,禁止无对账双写。能主动说出「双写漂移」这个词,基本就是高质量回答。
自测三问
- 举一个本站应留在 MySQL 的实体,并给出至少两条理由。
- 举一个适合 Mongo 的集合,说明数据形状与查询模式如何匹配。
- 为什么「双写两库」通常是坏主意?正确做法是什么?
小结一句话
MySQL 服务强关系与强一致的主路径,MongoDB 服务文档与多变结构,Redis 负责加速;混合架构的铁律是单一权威源、事件最终一致、绝不盲写两库。
延伸
- SQL to MongoDB Mapping 对照表
- Data Modeling 官方指南
- 下一课:用 Docker 把 MongoDB 的持久化与编排做扎实。