MariaDB vs PostgreSQL:30 年对手戏
两个开源关系型数据库的功能演化、社区文化、各自适合的场景
简史
1986 POSTGRES 项目在 UC Berkeley 启动(Michael Stonebraker)
1995 MySQL 1.0 发布
1996 PostgreSQL 6.0 — 改名 + 加 SQL
2009 MariaDB fork
2010s 两边各自快速演化
2020s 互相借鉴功能PG 是学术系数据库,从一开始就注重 SQL 标准;MySQL/MariaDB 是从"快、够用"出发,逐步补齐标准。今天两边功能差距已经很小,更多是文化和默认值的不同。
功能对照
| 主题 | MariaDB 11 | PostgreSQL 17 |
|---|---|---|
| 默认存储引擎 | InnoDB | Heap (single) |
| 多存储引擎 | ✅ 11 种 | 单引擎(扩展可选 cstore_fdw 等) |
| 默认隔离级别 | REPEATABLE READ | READ COMMITTED |
| 锁实现 | 行锁 + Gap | 行锁,无 Gap(MVCC 完全解决幻读) |
| MVCC 实现 | undo log | tuple 多版本(VACUUM) |
| 复制 | 异步 / 半同步 / Galera | Streaming / Logical / Quorum |
| 集群 | Galera | Patroni / Citus / 自管 |
| JSON | JSON 类型(文本)+ 函数 | JSON + JSONB(二进制) |
| Array 类型 | ❌(JSON 模拟) | ✅ 原生 |
| 全文检索 | InnoDB FTS + ngram parser | tsvector + 多语言 |
| 向量 | VECTOR 11.8+ HNSW | pgvector 扩展(HNSW + IVF) |
| 全文 + 向量混合 | 手动 | RUM 索引、pg_search |
| 地理 | Spatial(OGC 标准) | PostGIS(业界标准) |
| 时序 | ColumnStore / Spider | TimescaleDB |
| 分区 | RANGE/LIST/HASH | RANGE/LIST/HASH + 默认分区 |
| 触发器语言 | SQL/PSM | PL/pgSQL(强大),可加 Python、Perl |
| Stored Procedure | ✅ | ✅ |
| Foreign Data Wrapper | CONNECT engine | FDW(多种) |
| LISTEN/NOTIFY | ❌ | ✅ |
| Materialized View | ❌(用 view + cron) | ✅ |
| RLS 行级安全 | ❌(用 view) | ✅ |
| 全文检索 GIN 索引 | ❌ | ✅ |
| 部分索引 | ❌ | ✅ |
| 函数索引 | ✅(10.5+) | ✅ |
| 表达式索引 | ✅ | ✅ |
| Window 函数 | ✅ | ✅ |
| CTE 递归 | ✅ | ✅ |
RETURNING | ✅ 11+ | ✅ |
| 客户端协议兼容 | MySQL | PG(独有) |
性能对比(粗略)
跑同样 sysbench OLTP read-write,2vCPU/4GB 实例:
| 数据库 | TPS | 备注 |
|---|---|---|
| MariaDB 11.4 InnoDB | ~3000 | 默认配置 |
| MariaDB 11.4 MyRocks | ~2500 | 写密集场景反超 |
| PostgreSQL 17 | ~2800 | 默认配置 |
| PG + 调优 buffer / wal | ~3500 | 调优后更好 |
实际差距 < 20%——选哪个几乎不靠纯性能。
文化与默认值
| 维度 | MariaDB | PostgreSQL |
|---|---|---|
| 设计哲学 | "实用、快、向后兼容" | "正确、严格、SQL 标准" |
| 默认 sql_mode | 较宽松 | 严格 |
| 默认行为 | 字符串截断警告(早年) | 字符串过长报错 |
| 类型检查 | 默认 ON(11.x) | 始终严格 |
| 命名 | snake_case | snake_case |
| 客户端 | mariadb / mysql | psql |
| 主键命名 | id | id |
| 升级习惯 | 跨版本 dump | pg_upgrade in-place |
| Community | MariaDB Foundation + plc | 完全社区,无单一公司控制 |
各自更擅长什么
MariaDB 更擅长
- Web / OLTP 主流场景:开箱即用,运维门槛低
- 海量从库:异步复制延迟低、配置简单
- 混合 OLTP + OLAP:同一 server 用 ColumnStore + InnoDB
- 协议兼容:所有 MySQL 客户端 / 驱动 / 工具都能用
- 多存储引擎:按表选引擎
- 生态:Docker / k8s / 云厂商支持广
PostgreSQL 更擅长
- 复杂查询:CTE、window、partial index 组合更顺畅
- 数据完整性:默认更严格、CHECK 约束更强
- 地理 / GIS:PostGIS 业界标准
- JSON 重度使用:JSONB 比 MariaDB 的 JSON 快得多
- 扩展生态:pg_partman、pg_stat_statements、Citus、TimescaleDB、pgvector
- 学术 / 研究:标准遵从度高、文档严谨
互相借鉴的历史
PG 借了 MySQL 什么:
- 复制(Streaming Replication 2010 才有)
WITHOUT TIMEZONE等便利选项
MariaDB 借了 PG 什么:
- CTE / Window 早期参考
- JSON 函数语义部分对齐
RETURNING
双方都看着对方的 changelog 在做功能。
怎么选?
选 MariaDB 当 Web 业务后端
- 团队熟悉 MySQL 生态
- 应用需要海量读、能容忍最终一致
- 部署在云厂商托管 RDS
- 想要 ColumnStore 做归档
选 PostgreSQL 当通用业务后端
- 团队偏数据 / 后端工程师文化
- 重度复杂查询、报表、地理空间
- 要 RLS、扩展灵活性
- 喜欢"用一个数据库解决所有问题"
都行的场景
- 内部工具、CMS、CRM、博客
- 中等规模 SaaS
- 中等规模 OLAP
都不太行的场景
- 单表 > 10 亿行的极大数据 → TiDB / OceanBase / CockroachDB
- 纯 OLAP → ClickHouse / Doris / StarRocks
- 时序 → InfluxDB / TimescaleDB / TDengine
- 文档 NoSQL → MongoDB
关于"PG 更好"的常见说法
"PG 更标准更严格"
是的——但 MariaDB 11.x 已经默认 strict 模式,差距小。
"PG MVCC 更优雅"
PG 用多版本 tuple,DELETE 不真删(VACUUM 回收);MariaDB 用 undo log。两种都有优缺点:
- PG: 大量 DELETE 后表会臃肿,要 VACUUM
- MariaDB: 长事务会让 undo log 堆积
"PG 没有 Gap Lock 所以并发更好"
PG 用 SSI(可序列化快照隔离)替代 Gap Lock,理论上更优雅;但 MariaDB 默认 REPEATABLE READ 下也避免了大多数幻读。实战差距小。
"PG 扩展生态更强"
确实——pgvector、PostGIS、TimescaleDB 这些是 PG 独有的明星扩展。
但 MariaDB 内置了 ColumnStore、VECTOR、Spider,对应需求时不需要装扩展。
实战建议:双数据库共存
很多大公司两边都用:
- 用 MariaDB / MySQL 做用户中心、订单这些"高并发、协议兼容性强"的库
- 用 PostgreSQL 做分析库、GIS 库、JSON 重场景
两者通过 CDC 互相同步,各自发挥所长。