PostgreSQL、MySQL、MongoDB、ClickHouse:怎么选,什么时候用哪个
面试题:你的项目里为什么选 PostgreSQL 而不是 Mysql?什么时候会考虑 MongoDB 或 ClickHouse?
回到选型背后的维度上:数据长什么样、查询是什么形态、一致性要求多高。
这篇文章把四个库放到同一组维度下拆:先说每个库"出生时是为什么问题设计的",再给场景对照表。文中的判断是通用工程共识,不代表任何一家公司的具体选型,也没有虚构性能数字。
一、先看它们各自解决什么问题
四个库不是同一道题的四个选项,是四道题的四个答案。
MySQL:关系型,出生在 Web 时代,生态最厚。中小规模的事务型业务(用户、订单、后台管理)默认选项之一,招人好招、运维工具成熟、踩坑的人多所以坑都有名字。
PostgreSQL:同样是关系型,但走的是"功能全"的路线——事务实现更严格、类型系统丰富(JSONB、数组、范围类型)、插件生态(PostGIS 地理、pgvector 向量)。很多"业务还没定型、数据形态可能变"的场景,PG 的表达力更强。
MongoDB:文档型,为"一条记录天然是一棵 JSON 树"设计。字段结构变化频繁、嵌套深、读写以整条文档为单位时省掉 ORM 拆装;多表 join 重、事务要求弱(注意:4.0 之后有事务,但成本高、不是它的主场)的场景。
ClickHouse:列式 OLAP,为"亿级数据上跑聚合分析"设计。单表宽表的 count、group by、按时间切片快得离谱,但单条 update/delete 是弱项、join 也不是主场。它是分析库,不是业务库。
一句话定位:MySQL / PG 管"业务的真相",MongoDB 管"文档的自然形态",ClickHouse 管"历史的统计"。
二、按三个维度拆开比
1. 数据模型与 schema
| MySQL | PostgreSQL | MongoDB | ClickHouse | |
|---|---|---|---|---|
| 模型 | 行式,表 | 行式,表 + 丰富类型 | 文档(BSON) | 列式,宽表 |
| schema | 强约束,改表成本随数据量涨 | 强约束,DDL 相对从容 | 弱约束,字段随文档走 | 查询侧灵活,表结构偏"一次设计长期追加" |
| 嵌套结构 | JSON 类型能用但别当饭吃 | JSONB 带索引,真能用 | 原生就是文档 | 不擅长,分析视角要拍平 |
判断点:字段三个月后会不会变?嵌套有多深? 字段稳定、关系清晰 → 关系型;一条记录就是一棵树、字段跟着业务形态走 → 文档型。
2. 事务与一致性
| 能力 | 适合 | |
|---|---|---|
| MySQL (InnoDB) | ACID 成熟,行锁 | 订单、库存、账务这类"错一笔就出事"的数据 |
| PostgreSQL | ACID 严格,MVCC 实现干净 | 同上,且对隔离级别语义要求更较真的场景 |
| MongoDB | 4.0+ 支持多文档事务,但开销大 | 事务是兜底,不是设计前提 |
| ClickHouse | 基本不管事务 | 统计口径允许"最终对齐",不追求实时强一致 |
判断点:两个写操作必须同时成或同时败吗? 是 → 关系型;"这条数据晚半秒变完整"也能接受 → 文档型也行;"报表晚五分钟刷新"无所谓 → 分析库。
3. 查询形态
这是最容易被忽视的一维,也是 ClickHouse 和前三个的分水岭。
- 点查 + 小范围更新(按 id 取用户、改订单状态)→ 行式库的主场
- 多表关联 + 复杂条件 → PG / MySQL;join 复杂、窗口函数用得多,PG 表达力更顺
- 整条文档读写、按字段模糊匹配 → MongoDB
- 大批量扫描 + 聚合(count / group by / 时间切片) → ClickHouse,行式库在这个形态下是硬扛
一个常见的真实错位:拿 MySQL 当分析库用。几千万行的日志表上跑 group by,每次都把库拖到响应变慢——业务点查和后台报表互相打死。这时候正确的动作不是先调优,是把分析负载挪走(ClickHouse,或者哪怕是预聚合 + 缓存)。
三、场景对照表
| 场景 | 首选 | 理由 / 备注 |
|---|---|---|
| 用户、订单、账务等核心交易 | MySQL / PG | 事务必须硬;两者都行,看团队栈 |
| 后台管理、配置、权限 | MySQL / PG | 数据量小,哪个都撑得住,别花心思 |
| 业务字段结构多变、文档嵌套深(表单引擎、动态属性) | MongoDB | 省掉频繁改表和 ORM 拆装 |
| 地理位置存储与空间查询 | PostgreSQL + PostGIS | 地图类功能的事实标准 |
| 日志、埋点、行为流水的查询分析 | ClickHouse | 写入吞吐 + 聚合速度都是主场 |
| 报表大盘、多维统计 | ClickHouse(或预聚合方案) | 别让业务库扛分析 |
| 全文搜索 | 都不是最优 | 交给 Elasticsearch / MeiliSearch 这类专职引擎 |
| 缓存热点 | 都不是 | Redis 干的事 |
| 向量检索 / AI 场景 | PostgreSQL + pgvector | RAG 类应用的常见轻量方案 |
再说一遍那张表背后的原则:先问"这是什么负载",再问"哪个库"。 负载形态对了,MySQL 和 PG 很多场景互换都行;负载形态错了,"选了正确的库"也救不了。
四、几个常见误区
误区一:MongoDB 没 schema,所以更简单。 它没的是服务端约束,schema 只是从数据库挪到了代码里。文档结构失控的时候,"这条记录有没有 phone 字段"得靠翻代码确认,比 desc 一张表难受得多。文档型换来的是灵活性,付掉的是约束。
误区二:ClickHouse 快,所以啥都往里塞。 它快是有条件的:列式、批量写入、读少写多追加式。拿它当业务库用——频繁单条更新、事务、点查——会比 MySQL 还难受。它的 slogan 可以记成"快是省出来的":不存行、不维护事务、不做随机更新,才换来聚合快。
误区三:PG 比 MySQL 强,所以新项目无脑 PG。 PG 功能确实更多,但 MySQL 生态、运维熟悉度、云厂商支持在国内仍然更厚。中小团队"大家都会"本身就是一个硬指标,选型算的不是单项分,是总分。
误区四:选了就定终身。 实际工程里常见的是组合:MySQL 放交易数据,ClickHouse 放行为流水,Redis 抗热点,ES 管搜索。"选哪个"的前提往往是"已经有哪个",增量决策比推倒重来常见得多。
五、面试里可以这样回答
先看负载形态而不是先报库名。核心交易数据要求 ACID,那就是 MySQL 或 PostgreSQL 二选一,两者都够,差别在生态和团队熟悉度;PG 在复杂查询、JSONB、还有 PostGIS、pgvector 这些扩展上表达力更强。如果数据是文档形态、字段变化频繁、整条读写为主,比如表单引擎这类,我会考虑 MongoDB,但会想清楚 schema 约束从服务端挪到代码层之后怎么管。如果是日志埋点、亿级行的聚合分析,那就是 ClickHouse 的主场,把分析负载从业务库上拆出去,别让报表查询打死交易。
然后补一句实际项目的例子:当时数据是什么形态、查询长什么样、为什么这么选、踩了什么坑。选型这件事上,"为什么不是另一个"往往比"为什么是这个"更能看出人有没有真用过。
纸上得来终觉浅,绝知此事要躬行。