关系数据库的世界,表面上看是“都支持 SQL、都有事务、都有索引”,但真到了选型和排障的时候,MySQL、PostgreSQL、Oracle、SQL Server 之间的差异远比想象中大——连接是进程还是线程、表是堆表还是索引组织表、MVCC 把旧版本放在哪、默认隔离级别是什么……这些“底层选择”直接决定了性能特征、运维方式和适用场景。
这篇就把这四位最主流的选手放在一起做一次横向对比。不堆砌参数,而是聚焦那些**“同样叫 RDBMS、实现却截然不同”**的关键维度,最后给出选型建议。
顺带:本文是我数据库系列的横向补充——系列纵向讲了存储引擎、索引、事务、MVCC、复制等专题(见《数据库系列》一至十),这篇把它们横向铺开,看看四大库在每个维度上各自怎么选。
一、四位选手速览
| MySQL | PostgreSQL | Oracle Database | SQL Server | |
|---|---|---|---|---|
| 出身 | 1995,Monty 创立;现属 Oracle 公司 | 1996,伯克利 POSTGRES 衍生;社区 + EDB 等 | 1977,Oracle 公司 | 1989,微软(源自 Sybase 合作,后独立) |
| 许可证 | GPL + 商业双许可 | PostgreSQL License(类 BSD,极宽松) | 专有商业(昂贵) | 专有商业 |
| 定位 | Web/互联网标配,简单可靠 | “最先进的开源 RDBMS”,功能全 | 企业级旗舰,功能最全 | 微软生态企业标配 |
| 谁在用 | 海量互联网应用 | 复杂业务 / AI / 地理 / 时序 | 金融 / 电信 / 大型企业 | .NET / Windows 企业、Azure |
二、一张表看全貌
| 维度 | MySQL (InnoDB) | PostgreSQL | Oracle | SQL Server |
|---|---|---|---|---|
| 连接模型 | 线程 / 连接 | 进程 / 连接(fork,较重) | 进程(dedicated)/ 共享服务器 | 线程 / 连接 |
| 存储模型 | 索引组织表(聚簇) | 堆表 | 堆表(默认),可选 IOT | 聚簇(默认),或堆表 |
| 默认隔离级别 | REPEATABLE READ | READ COMMITTED | READ COMMITTED | READ COMMITTED(悲观) |
| MVCC 旧版本存放 | undo log + purge | 堆内多版本 + VACUUM | undo 段 | tempdb 版本库(开启快照时) |
| 索引种类 | B+树、Hash、全文、空间(有限) | B树、Hash、GiST、GIN、BRIN、SP-GiST | B树、位图、反键、域索引 | 聚簇/非聚簇、列存、全文、空间 |
| 复制 | binlog 主从 / 半同步 / MGR | 流复制(物理)/ 逻辑复制 | Data Guard / GoldenGate / RAC | AlwaysOn AG / FCI |
| 多活 | MGR 多主(有限制) | 无原生(外部 Patroni 等) | RAC(共享存储多实例) | 无原生多主 |
| 过程语言 | 存储过程(SQL/PSM 风格) | PL/pgSQL(+ Python/Perl…) | PL/SQL(业界标杆) | T-SQL |
| 可扩展性 | 插件式存储引擎 | 极强(自定义类型/算子/扩展) | 强(官方闭源) | CLR(.NET 扩展) |
| JSON | JSON 类型 + 函数 | JSON / JSONB(可索引,最强) | JSON(12c+) | NVARCHAR + 函数 |
| 云服务 | Aurora MySQL / RDS | Aurora PG / Neon / Supabase | OCI Autonomous DB | Azure SQL |
下面挑几个最能体现“工程哲学差异”的维度展开。
三、架构与连接模型:进程 vs 线程
最容易感知的差异:一个连接占一个进程,还是占一个线程?
- MySQL / SQL Server:线程模型。每个连接一个线程,相对轻量,连接数上限较高。
- PostgreSQL:进程模型(fork)。每个连接是一个独立的后端进程。连接一多,内存和 fork 开销就大——所以 PG 高并发场景几乎必备连接池(pgbouncer / Pgpool)。“PG 吃连接数”是经典运维话题,根因就在这。
- Oracle:可选。dedicated server(每连接一进程)适合长连接;shared server(dispatcher + 共享服务器进程)适合海量短连接。
这一条直接决定了你的连接数规划、内存占用,以及“为什么 PG 要 pgbouncer 而 MySQL 基本不用”。
四、存储模型:堆表 vs 索引组织表
这是理解四大库性能差异的钥匙(《数据库系列(二)》详细讲过,这里横向对照)。
- 索引组织表(IOT / 聚簇):数据本身就存在主键的 B+ 树叶节点里,主键即数据。
- MySQL InnoDB(默认)、SQL Server(默认建聚簇索引)、Oracle(可选 IOT)。
- 优点:主键点查 / 范围扫极快;代价是二级索引存的是主键值,往往要“回表”。
- 堆表(heap):数据和索引分离,索引指向行的物理位置(PG 的 ctid / SQL Server 的 RID)。
- PostgreSQL(默认)、Oracle(默认)、SQL Server(无聚簇索引时)。
- 优点:无主键也能存、二级索引直接定位行、更新更灵活(配合 MVCC,新版本可写到任意空闲块)。
一句话:InnoDB / SQL Server 默认“表就是一棵主键树”;PostgreSQL / Oracle 默认“表是一堆数据 + 若干索引指过去”。 这决定了它们在主键查询、二级索引回表、更新碎片上的不同行为。
五、事务与 MVCC:同一个思想,四种实现
四大库都实现了 MVCC(读不阻塞写),但旧版本放在哪、谁来清理各不相同——这是最见功底的地方:
- MySQL InnoDB:数据页内就地更新,旧版本写入 undo log;读旧版本时用 undo 重构。后台 purge 线程清理不再需要的 undo。
- PostgreSQL:旧版本直接作为新元组留在表堆里(用
xmin/xmax标记可见性),表会“膨胀”,靠 VACUUM(autovacuum)回收空间。“PG 要调 autovacuum”是运维必修课。 - Oracle:DML 的前镜像写入 undo 表空间(undo 段),读一致性从 undo 重构。最成熟的实现,也是 InnoDB / PG 思路的“祖师爷”。
- SQL Server:默认 RC 是悲观锁(加锁、不存版本);开启快照隔离(RCSI / SI)后,旧版本写入 tempdb 的版本库。
默认隔离级别也值得注意(经典考点):
| 数据库 | 默认隔离级别 |
|---|---|
| MySQL InnoDB | REPEATABLE READ(用间隙锁 / next-key 锁防幻读,较激进) |
| PostgreSQL | READ COMMITTED |
| Oracle | READ COMMITTED(只支持 RC 与 SERIALIZABLE) |
| SQL Server | READ COMMITTED(悲观;可切 RCSI) |
MySQL 默认 RR 是个“异类”——大多数库默认 RC。做跨库迁移时,这点锁行为差异要特别留心(RR + 间隙锁容易引发意料外的锁冲突)。
六、索引能力
- PostgreSQL 索引最丰富:B-tree、Hash、GiST(范围 / 几何)、GIN(数组 / 全文 / JSONB 利器)、BRIN(海量有序数据)、SP-GiST;还支持部分索引、表达式索引、覆盖索引。配合 JSONB / 数组,PG 能干很多“NoSQL 的活”。
- MySQL:以 B+ 树为主,加全文、空间索引,以及 8.0+ 的降序 / 函数 / 不可见索引;类型相对少,但 InnoDB 聚簇 B+ 树在主键点查和范围扫上极高效。
- Oracle:B 树、位图索引(适合低基数列,数据仓库利器)、反键索引(消除热点)、域索引;分区与索引组合极其丰富。
- SQL Server:聚簇 / 非聚簇、列存索引(列式,OLAP 利器)、全文、空间;内存优化表(Hekaton)还有专属的哈希 / 非聚簇索引。
七、SQL 方言与可扩展性
- 过程语言:Oracle PL/SQL 是业界标杆、功能最全;SQL Server T-SQL 在微软生态根深蒂固;PostgreSQL PL/pgSQL 仿照 PL/SQL,还能装 PL/Python、PL/V8 等多语言;MySQL 的存储过程相对朴素。
- 可扩展性(PG 的杀手锏):PostgreSQL 允许自定义类型、操作符、索引方法、聚合,并通过
CREATE EXTENSION装载扩展——于是有了 PostGIS(地理空间)、pgvector(AI 向量)、TimescaleDB(时序)等“长在 PG 上的专用数据库”。这种“一个内核、千变扩展”的生态,是其它三者没有的。 - CLR(SQL Server):可以用 C# / .NET 写存储过程、类型、函数,和微软技术栈无缝衔接。
- Oracle:功能强但闭源,扩展主要靠官方和 PL/SQL 包。
八、复制与高可用
| 复制方式 | 多活能力 | |
|---|---|---|
| MySQL | binlog 异步 / 半同步主从、MGR 组复制(基于 Paxos)、InnoDB Cluster | MGR 多主(有冲突约束) |
| PostgreSQL | 物理流复制(WAL,同步 / 异步)、逻辑复制(10+);HA 靠 Patroni / repmgr 等外部编排 | 无原生多主 |
| Oracle | Data Guard(物理 / 逻辑备库)、Active Data Guard(只读备库)、GoldenGate(逻辑);RAC(共享存储 + 多实例) | RAC 真·多实例 active-active |
| SQL Server | AlwaysOn AG(日志同步,可读次要副本)、FCI(故障转移集群) | 无原生多主 |
亮点:Oracle RAC 是“共享存储 + 多实例”的真多活架构,独门绝技(也贵);MySQL MGR 提供了开源版的“类 RAC”多主能力;PostgreSQL 的 HA 高度依赖外部编排(Patroni),原生只有主从。
九、生态与云
- MySQL:互联网事实标准,配合 Vitess / PlanetScale、Aurora MySQL,云原生方案最成熟。
- PostgreSQL:开源生态最活跃,Aurora PG、AlloyDB、Neon、Supabase 百花齐放;AI 时代因 pgvector 重新翻红。
- Oracle:企业级护城河深,Exadata 一体机、OCI Autonomous DB,但云转型相对慢。
- SQL Server:和 Windows / .NET / Azure 深度绑定,Azure SQL 是云上主力。
十、选型建议(按场景)
- 互联网 / Web 应用,读多写多,追求简单和生态 → MySQL。运维资料最多、人才最多、云方案最成熟。
- 业务逻辑复杂,要 JSONB / 数组 / 全文 / 地理空间 / AI 向量,追求 SQL 标准与扩展性 → PostgreSQL。“一个 PG 顶好几个专用库”。
- 金融 / 电信 / 大型企业,要 RAC 真多活,要最全功能,预算充足 → Oracle。功能天花板最高,TCO 也最高。
- 微软技术栈(.NET / Windows / Azure),企业 OLTP + BI 一体 → SQL Server。和现有基础设施最贴合。
- 嵌入式 / 移动端 / 边缘 → SQLite(不在四位之列,但几乎无处不在)。
- MySQL 的开源替代 → MariaDB(原作者 Monty 分叉,兼容 MySQL,部分场景特性 / 性能有差异)。
结语
四大关系数据库,表面都是“SQL + 事务 + 索引”,底层却是四套不同的工程哲学:连接用进程还是线程、表是堆还是树、MVCC 旧版本放哪、默认隔离多激进、复制怎么做多活、能不能长出扩展生态。这些差异没有绝对优劣,只有“和你的场景、团队、基础设施是否匹配”。
选型的本质,不是选“最好的数据库”,而是选**“约束下最合适的数据库”**——数据规模、一致性要求、HA 形态、团队技能栈、预算,共同决定了答案。理解了这张横向对比,你就能在“为什么是它而不是另一个”这个问题上,给出有底气的回答。