正文
既然
MySQL 8
和
PostgreSQL 10
已经发布了,现在是时候回顾一下这两大开源关系型数据库是如何彼此竞争的。
在这些版本之前,人们普遍认为,Postgres 在功能集表现更出色,也因其“学院派”风格而备受称赞,MySQL 则更善长大规模并发读/写。
但是随着它们最新版本的发布,两者之间的差距明显变小了。
特性比较
让我们来看看我们都喜欢谈论的“时髦”功能。
特性
|
MySQL 8
|
PostgreSQL 10
|
查询 & 分析
|
|
|
公用表表达式 (CTEs)
|
✔ New
|
✔
|
窗口函数
|
✔ New
|
✔
|
数据类型
|
|
|
JSON 支持
|
✔ Improved
|
✔
|
GIS / SRS
|
✔ Improved
|
✔
|
全文检索
|
✔
|
✔
|
可扩展性
|
|
|
逻辑复制
|
✔
|
✔ New
|
半同步复制
|
✔
|
✔ New
|
声明式分区
|
✔
|
✔ New
|
过去经常会说 MySQL 最适合在线事务,PostgreSQL 最适合分析流程。但现在不是了。
公共表表达式(CTEs) 和窗口函数是选择 PostgreSQL 的主要原因。但是现在,通过引用同一个表中的 boss_id 来递归地遍历一张雇员表,或者在一个排序的结果中找到一个中值(或 50%),这在 MySQL 上不再是问题。
在 PostgreSQL 中进行复制缺乏配置灵活性,这就是
Uber 转向 MySQL
的原因。但是现在,有了逻辑复制特性,就可以通过创建一个新版本的 Postgres 并切换到它来实现零停机升级。在一个巨大的时间序列事件表中截断一个陈旧的分区也要容易得多。
就特性而言,这两个数据库现在都是一致的。
有哪些不同之处呢?
现在,我们只剩下一个问题 —— 那么,选择一个而不选另一个的原因是什么呢?
生态系统
是其中一个因素。MySQL 有一个充满活力的生态系统,包括 MariaDB、Percona、Galera 等等,以及除 InnoDB 以外的存储引擎,但这也可能是和令人困惑的。Postgres 的高端选择有限,但随着最新版本引入的新功能,这会有所改变。
治理
是另一个因素。当 Oracle(或最初的 SUN)收购 MySQL时,每个人都担心他们会毁掉这个产品,但在过去的十年里,这并不是事实。事实上,在收购之后,发展反倒加速了。而 Postgres 在工作管理和协作社区方面有着丰富的经验。
基础架构
不会经常改变,虽然近来没有对这方面的详细讨论,这也是值得再次考虑的。
来复习下:
特性
|
MySQL 8
|
PostgreSQL 10
|
架构
|
单进程
|
多进程
|
并发
|
多线程
|
fork(2)
|
表结构
|
聚簇索引
|
堆
|
页压缩
|
Transparent
|
TOAST
|
更新
|
In-Place / Rollback Segments
|
Append Only /
HOT
|
垃圾回收
|
清除线程
|
自动清空进程
|
事务日志
|
REDO Log (WAL)
|
WAL
|
复制日志
|
Separate (Binlog)
|
WAL
|
进程vs线程
当
Postgres 派生出一个子进程
来建立连接时,
每个连接最多可以占用 10MB
。与 MySQL 的线程连接模型相比,它的内存压力更大,在 64 位平台上,线程的默认堆栈大小为
256KB。(当然,线程本地排序缓冲区等使这种开销变得不那么重要,即使在不可以忽略的情况下,仍然如此。)
尽管“
写时复制
”保存了一些与父进程共享的、不可变的内存状态,但是当您有 1000 多个并发连接时,基于流程的架构的基本开销是很繁重的,而且它可能是容量规划的最重要的因素之一。
也就是说,如果你在 30 台服务器上运行一个 Rails 应用,每个服务器都有 16 个 CPU 核心 32 线程,那么你有 960 个连接。可能只有不到 0.1% 的应用会超出这个范围,但这是需要记住的。
聚簇索引 vs 堆表
聚簇索引
是一种表结构,其中的行直接嵌入其主键的 b 树结构中。一个(非聚集)堆是一个常规的表结构,它与索引分别填充数据行。
有了聚簇索引,当您通过主键查找记录时,单次 I/O 就可以检索到整行,而非集群则总是需要查找引用,至少需要两次 I/O。由于外键引用和 JOIN 将触发主键查找,所以影响可能非常大,这将导致大量查询。
聚簇索引的一个理论上的缺点是,当您使用二级索引进行查询时,它需要遍历两倍的树节点,第一次扫描二级索引,然后遍历聚集索引,这也是一棵树。
但是,如果按照现代
表设计的约定
,将一个自动增量整数作为主键
[1]
——它被称为
代理键
——那么拥有一个
聚集索引几乎总是可取的
。更重要的是,如果您做了大量的 ORDER BY id 来检索最近的(或最老的)N 个记录的操作,我认为这是很适用的。