主流关系数据库横向对比:MySQL / PostgreSQL / Oracle / SQL Server 的架构、特性与选型

关系数据库的世界,表面上看是“都支持 SQL、都有事务、都有索引”,但真到了选型和排障的时候,MySQL、PostgreSQL、Oracle、SQL Server 之间的差异远比想象中大——连接是进程还是线程、表是堆表还是索引组织表、MVCC 把旧版本放在哪、默认隔离级别是什么……这些“底层选择”直接决定了性能特征、运维方式和适用场景。

这篇就把这四位最主流的选手放在一起做一次横向对比。不堆砌参数,而是聚焦那些**“同样叫 RDBMS、实现却截然不同”**的关键维度,最后给出选型建议。

顺带:本文是我数据库系列的横向补充——系列纵向讲了存储引擎、索引、事务、MVCC、复制等专题(见《数据库系列》一至十),这篇把它们横向铺开,看看四大库在每个维度上各自怎么选。

一、四位选手速览

MySQLPostgreSQLOracle DatabaseSQL Server
出身1995,Monty 创立;现属 Oracle 公司1996,伯克利 POSTGRES 衍生;社区 + EDB 等1977,Oracle 公司1989,微软(源自 Sybase 合作,后独立)
许可证GPL + 商业双许可PostgreSQL License(类 BSD,极宽松)专有商业(昂贵)专有商业
定位Web/互联网标配,简单可靠“最先进的开源 RDBMS”,功能全企业级旗舰,功能最全微软生态企业标配
谁在用海量互联网应用复杂业务 / AI / 地理 / 时序金融 / 电信 / 大型企业.NET / Windows 企业、Azure

二、一张表看全貌

维度MySQL (InnoDB)PostgreSQLOracleSQL Server
连接模型线程 / 连接进程 / 连接(fork,较重)进程(dedicated)/ 共享服务器线程 / 连接
存储模型索引组织表(聚簇)堆表堆表(默认),可选 IOT聚簇(默认),或堆表
默认隔离级别REPEATABLE READREAD COMMITTEDREAD COMMITTEDREAD COMMITTED(悲观)
MVCC 旧版本存放undo log + purge堆内多版本 + VACUUMundo 段tempdb 版本库(开启快照时)
索引种类B+树、Hash、全文、空间(有限)B树、Hash、GiST、GIN、BRIN、SP-GiSTB树、位图、反键、域索引聚簇/非聚簇、列存、全文、空间
复制binlog 主从 / 半同步 / MGR流复制(物理)/ 逻辑复制Data Guard / GoldenGate / RACAlwaysOn AG / FCI
多活MGR 多主(有限制)无原生(外部 Patroni 等)RAC(共享存储多实例)无原生多主
过程语言存储过程(SQL/PSM 风格)PL/pgSQL(+ Python/Perl…)PL/SQL(业界标杆)T-SQL
可扩展性插件式存储引擎极强(自定义类型/算子/扩展)强(官方闭源)CLR(.NET 扩展)
JSONJSON 类型 + 函数JSON / JSONB(可索引,最强)JSON(12c+)NVARCHAR + 函数
云服务Aurora MySQL / RDSAurora PG / Neon / SupabaseOCI Autonomous DBAzure 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 InnoDBREPEATABLE READ(用间隙锁 / next-key 锁防幻读,较激进)
PostgreSQLREAD COMMITTED
OracleREAD COMMITTED(只支持 RC 与 SERIALIZABLE)
SQL ServerREAD 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 包。

八、复制与高可用

复制方式多活能力
MySQLbinlog 异步 / 半同步主从、MGR 组复制(基于 Paxos)、InnoDB ClusterMGR 多主(有冲突约束)
PostgreSQL物理流复制(WAL,同步 / 异步)、逻辑复制(10+);HA 靠 Patroni / repmgr 等外部编排无原生多主
OracleData Guard(物理 / 逻辑备库)、Active Data Guard(只读备库)、GoldenGate(逻辑);RAC(共享存储 + 多实例)RAC 真·多实例 active-active
SQL ServerAlwaysOn 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 形态、团队技能栈、预算,共同决定了答案。理解了这张横向对比,你就能在“为什么是它而不是另一个”这个问题上,给出有底气的回答。