探索PostgreSQL:基础知识解析

发表时间: 2020-01-04 10:39


1 章 基础知识

PostgreSQL 是一款极其强大的数据库,它的很多特性可能是你前所未见

的。它的部分特性在其他知名数据库中也有,但名称可能不同。在深入

钻研官方手册之前,你需要了解一些核心概念,本章将为你介绍这些概

念,期间也会涉及其他数据库中的相关概念和术语。

本章将首先介绍如何下载和安装 PostgreSQL,然后会介绍一些必备的管

理工具和 PostgreSQL 术语。本书写作之时,PostgreSQL 10 已发布,我

们将重点介绍该版本的一些新特性。本章末尾会提供一些帮助资源,当

你需要额外的帮助或者报告 bug 时会用得到。

1.1 为什么应该选择PostgreSQL

PostgreSQL是一款企业级关系型数据库管理系统,即使与 Oracle、

Microsoft SQL Server、IBM DB2 等业界最好的商用数据库相比也毫不

逊色。PostgreSQL 之所以如此特别,是因为它不仅仅是一个数据库,还

是一个功能强大的应用开发平台。

PostgreSQL 的速度很快。大量的评测数据已经表明:与其商用以及开源

竞争对手相比,PostgreSQL 的速度要么远远胜出,要么旗鼓相当。

PostgreSQL 支持用多种编程语言编写存储过程和函数。除了系统自带的

C、SQL 和 PL/ pgSQL 编程语言外,还可以通过安装扩展包来支持

PL/Perl、PL/Python、PL/V8(又称为 PL/JavaScript)、PL/Ruby 以及

PL/R 等。这种支持多语言的能力可以让开发人员根据待解决问题的特

点来选择最合适的语言。比如可以使用 R 语言来解决统计和图形领域的

问题,通过 Python 来调用 Web 服务,通过使用 SciPy 库来进行科学计

算,通过 PL/V8 来进行数据验证、字符串处理和 JSON 数据处理,等

等。PostgreSQL 不但支持种类繁多的开发语言,使用过程也很简单:先

找到你需要的函数,看下它是用什么语言编写的,在 PostgreSQL 中安

装好支持该语言的扩展包,然后把代码复制过来就可以执行了。真的不

能更简单。

大多数数据库会限制用户只能使用预定义的数据类型,比如整型、字符

串、文本型、布尔型等。PostgreSQL 在数据类型的支持方面有两个优

势:不但支持比绝大多数数据库更丰富的原生数据类型,而且还允许用

户按需自定义数据类型。如果用户需要更复杂的数字类型,那么可以定

义包含两个浮点类型(float)的复合类型;如果需要定义一个三角形,

那么可以先定义一种“坐标”类型,然后再定义一种包含三个坐标的“三角形”

类型即可;

如果你对十二进制感兴趣,那么可以定义你自己的十二进制类型。值得注

意的是,要想自定义类型完全发挥出其威力,需要有相应的运算符和函数

来识别并配合它。因此,如果你自定义了一种特殊的数值类型,千万不要

忘了为它重定义配套的数学运算符。是的,你没看错,PostgreSQL 允许用

户重定义基础运算符(+、-、/、*)的实现逻辑。另外,用户自定义一种数

据类型后,PostgreSQL 会自动定义出一种基于该类型的数组类型。因此,

如果你定义了一种复合数据类型,那么该复合数据类型的数组类型自动就有

了,你无须做额外的定义工作。

PostgreSQL 会为每一张用户表自动创建一个数据类型定义。比如我们创

建了一张名为 dogs 的表,包含 breed(品种)、cuteness(可爱程

度)、barkiness(爱叫的程度)等字段,那么 PostgreSQL 会自动在后台

创建一个同名的dogs数据类型。这一特性将关系型数据库领域

的“表”概念与面向对象领域的“对象”概念紧密地联系到了一起,用户可

以像处理对象实例一样去处理记录。比如你可以创建一个函数来每次处

理一个或者一批对象实例。PostgreSQL 的很多第三方扩展包就利用该自

定义数据类型能力来优化性能,或者通过添加支持某个领域专用的特殊

SQL 语法来让业务代码更简洁和易于维护,或者实现一些在别的数据库

中完全不可能实现的功能。

我们建议用户不要把数据库仅仅当成一个数据容器,像 PostgreSQL 这

样的数据库其实是一个成熟而完整的应用开发平台。你会发现:强大的

数据库在手,其他一切都是过眼云烟。一旦你成了 SQL 高手,别人用

其他工具需要几小时才能完成的工作,你在数据库里只需要几秒钟。不

管是对比编码时间还是对比实际数据处理时间,效果都是如此。

近年来,我们看到很多 NoSQL 数据库异军突起,一时风头无两(我们

认为这里面有很大的炒作成分)。尽管 PostgreSQL 总体上看是一个关系

型数据库,但它其实也具备强大的处理非关系型数据的能力。比如

ltree 这个插件可以处理图数据,但我们几乎已经想不起它到底是何时被

加入到 PostgreSQL 中的;又比如 hstore 插件可以实现键值存储;还有

JSON 和 JSONB 类型可以提供类似 MongoDB 的文档操作能力。从很多

方面来看,PostgreSQL 甚至在“NoSQL”这个词出现之前就已经提供了那

些所谓的 NoSQL 特性。

如果从 Postgres95 正式改名为 PostgreSQL 开始算起,PostgreSQL 已经

诞生二十年了,但事实上它的历史可向前一直追溯到

1986年。 PostgreSQL 支持当前所有主流的操作系统,包括 Linux、Unix、

Windows 以及 Mac。目前每年会发布一个大版本,包含性能提升以及那

些不断超越关系型数据库功能极限的新功能。

从 1986 年开始,Stonebraker 教授发表了一系列论文,引入对象关系理念,

探讨了新的数据库的结构设计和扩展设计。1988 年,他发表了 Postgres 的

第一个原型设计,

1989 年 6 月发布了版本

1。因此 1986 年可视为 PostgreSQL 发展史的元年。——译者注

最后值得一提的是,PostgreSQL 不但是开源的,而且开源得非常彻底,

它的许可策略非常宽松。现在 PostgreSQL 社区由一群无私奉献的的开

发者和用户构成,他们并不把赚钱视为人生终极目标。如果需要新特

性,你可以自行贡献代码或者提出诉求。如果你试图修改 PostgreSQL

代码以为己所用,也不会有人起诉你。是成千上万用户的参与和贡献使

得 PostgreSQL 变成了它今日的模样。

到最后你会想:我为什么还要使用别家的数据库?PostgreSQL 已经提供

了我所需要的一切功能,而且还是免费的!你不再需要去阅读那些商业

数据库附带的密密麻麻的授权条款,来了解在一个八核虚拟机上支持 X

个并发连接所需要的费用是多少,也不需要了解每次升级后要再为许可

证加多少钱。

1

11.2 不适用PostgreSQL的场景

在为 PostgreSQL 做了这么多“鼓吹”之后,我们也应介绍一下它不适用

于哪些场景。

在不安装任何扩展包的情况下,PostgreSQL 需占用 100MB 以上的磁盘

空间,可以看出它的个头还是比较大的。因此,在一些存储空间极为有

限的小型设备上使用 PostgreSQL 是不合适的,把 PostgreSQL 当成简单

的缓存区来用也是不合适的,此时应选用一些更轻量级的数据库。

作为一款企业级数据库产品,PostgreSQL 对于安全是极其重视的。因

此,如果你在开发一个把安全管理放到应用层去做的轻量级应用,那么

PostgreSQL 完善的安全机制反倒会成为负担,因为它的角色和权限管理

非常复杂,会带来不必要的管理复杂度和性能损耗。此时可以考虑选用

SQLite 这样的单用户数据库,或者选用 FireBird 这样既能以客户端 / 服

务器模式运行也能以嵌入式单用户模式运行的数据库。

通过上述介绍可以看到,一般来说需要将 PostgreSQL 与别的数据库搭

配使用,使它们各展所长。一种常见的组合是把 Redis 或者 Memcache

当成 PostgreSQL 的查询缓存来用;另一种组合是用 PostgreSQL 做主数

据库,用 SQLite 存储离线数据来做离线查询。

令人遗憾的一个事实是,很多共享主机服务(多个用户共享同一个操作

系统实例)供应商并不支持预安装 PostgreSQL,或者只支持安装一个很

陈旧的版本。它们更喜欢预装较弱的 MySQL。对于一个 Web 设计人员

来说,用什么数据库并不是首要问题,此时 MySQL 可能能够满足要

求。但当用户的 SQL 技能不断提升,不再满足于写一写单表 select 或者

简单的 join 查询时,MySQL 的缺点就会暴露无遗。自本书第一版出版

以来,虚拟化技术的进步使得商业化的云主机服务得到了长足的发展,因此

拥有自己的独立云主机不再是一件很奢侈的事情。当用户拥有自己

的独立云主机时,就可以自由选择在上面安装什么软件。随着

PaaS(平台即服务)、DBaaS(数据库即服务)等云计算模式的流行,

PostgreSQL的发展前景向好。绝大多数的云服务厂商都提供

PostgreSQL 服务,其中比较著名的有 Heroku、Engine Yard、RedHat

OpenShift、Amazon RDS for PostgreSQL、Google Cloud SQL for

PostgreSQL、Amazon Aurora for PostgreSQL 以及 Microsoft Azure for

PostgreSQL。

1.3 如何获得PostgreSQL

若干年前,你只能通过手动编译源码的方式来安装 PostgreSQL。还好那

种痛苦的时代已经一去不复返了。当然,现在依然可以通过编译源码来

安装,但大多数用户会使用制作好的安装包来安装,只需敲击几下键盘

和鼠标就可以了。

如果你是首次安装 PostgreSQL,那么应该选择适用于你的操作系统平台

的最新稳定版发行包。PostgreSQL 官方站点的核心发布页面上维护了一

个列表,记录了适用于各操作系统的二进制包的下载地址。在附录

A

中,你会看到安装指导和一些定制版本的下载链接地址。

1.4 管理工具

PostgreSQL 常用的管理工具有四种:psql、pgAdmin、phpPgAdmin 和

Adminer。PostgreSQL 的核心开发团队维护着前三种,因此它们一般会

随着 PostgreSQL 的版本发布而同步更新。Adminer 并非 PostgreSQL 的

专用管理工具,它支持管理多种类型的关系型数据库,包括 SQLite、

MySQL、SQL Server 和 Oracle。除了刚刚提到的这四种以外,还有大量

优秀的管理工具,开源的和商业的都有。

1.4.1 psql

psql 是一种用于执行查询的命令行工具,每个 PostgreSQL 发行版中都

自带 psql(参见附录 B.4 节)。它有一些独特的功能,比如导入和导出

基于分隔符(逗号或者制表符等)格式的平面数据文件,以及生成简易

的 HTML 格式报表等。psql 是 PostgreSQL 从诞生之初就一直附带的命

令行工具,它是很多高级用户日常操作工具的不二之选,非常适用于只

有控制台字符界面而无图形用户界面的使用场景。另外,在通过 shell

脚本执行数据库操作时,psql 也是必备工具。不过新用户一般更喜欢使

用图形界面工具,而且也无法理解为什么“老”一代人会对命令行方式那

么执着。

1.4.2 pgAdmin

pgAdmin 是一款流行的免费的 PostgreSQL 图形界面管理工具。如果你

的 PostgreSQL 安装包里没有附带此工具,请从其官网单独下载安装。

pgAdmin 可在 PostgreSQL 支持的任意一种操作系统平台上运行。

即使你的数据库安装在只有控制台字符界面的 Linux 服务器上,只要你

在本地工作站上安装了 pgAdmin,也可以用这种强大的图形化工具对其进行管理。

pgAdmin 近期已经发布了它的第四个大版本,称为 pgAdmin4。该版本

对之前的 pgAdmin3 进行了彻底的重写,使用 Python 实现了“一套代码

两种模式运行”的效果,一种模式是作为桌面应用运行,另一种是在浏

览器中运行。pgAdmin4 当前的版本是 1.5。pgAdmin4 的首个版本是与

PostgreSQL 9.6 同时发布的,并被若干 PostgreSQL 发行版作为自带软件

一起打包发布。如前所述,pgAdmin4 既可以作为桌面应用运行,也可

以在浏览器中运行。

图 1-1 是 pgAdmin4 的界面示意图。图 1-1pgAdmin4 的树状视图

如果你对 PostgreSQL 还不太熟悉,那么 pgAdmin 毫无疑问是你开始

PostgreSQL 学习之旅的最佳入口。只需在主界面上摸索一下,你就可以

对 PostgreSQL 的丰富功能一览无遗。如果你正打算逃离 Microsoft SQL

Server 阵营,并且习惯于 SQL Server 的 Management Studio,那么很快

就能适应 pgAdmin。

相比 pgAdmin3,pgAdmin4 还有一些短板,但它正在快速补齐并在很多

方面都超过了 pgAdmin3。即便如此,如果你是 PgAdmin3 的长期用户

并且短期内无法切换到 pgAdmin4,那么你可以继续使用 BigSQL 公司

提供的 pgAdmin3 LTS(长期支持)版,在对 pgAdmin4 进行完善测试

后再切换过去。请务必牢记,pgAdmin4 才是 pgAdmin 未来的主力版

本,pgAdmin3 只会维持现状,不会再有什么发展。

1.4.3 phpPgAdmin

phpPgAdmin 是一种免费的基于 Web 页面的管理工具,其界面如图 1-2

所示。它是从流行的 MySQL 管理工具 phpMyAdmin 移植而来的,二者

的差别主要在于 phpPgAdmin 新增了对 PostgreSQL 的 schema、过程式

语言、类型转换器、运算符等对象的管理功能。如果你对 phpMyAdmin

很熟悉,会发现 phpPgAdmin 的界面风格与其完全类似。图 1-2phpPgAdmin

1.4.4 Adminer

如果你正在寻找一款除了能够管理 PostgreSQL,还能管理别的数据库的

整合型工具,那么 Adminer 将是你合适的选择。Adminer 是一款轻量级

的开源 PHP 应用程序,可以在同一套图形界面上管理 PostgreSQL、

MySQL、SQLite、SQL Server 以及 Oracle 等多种数据库。

Adminer 有一种独特的功能让我们印象深刻:它能够以图形化方式展示

数据库中的对象,并将外键约束关系以连接线的方式展示出来。另外,

整个 Adminer 程序的本体仅包含一个 PHP 文件,非常简洁,这可以大

大减少你安装部署时的麻烦。

图 1-3 中,左侧是登录屏幕的截图,右侧是表间关系图形化后呈现的效

果。很多用户会因为登录屏幕上没有填写端口号的地方而感到困惑。如

果 PostgreSQL 使用标准的 5432 侦听端口,那么登录时不填也没问题;

但如果不是,就需要在服务器名称后面加上端口号,注意用冒号分隔主

机名和端口号,如图 1-3 所示。图 1-3Adminer

对于简单的查询和修改操作来说,Adminer 的功能是足够的。但为了支

持多种数据库,Adminer 的功能体系已经被裁剪成了各数据库均支持的

最小公共集合,因此你无法实现 PostgreSQL 所特有的一些操作,比如

创建新用户、授予权限、查询当前权限列表等。Adminer 为了与它所支

持的各家数据库在概念上保持兼容和通用而将每个 schema 当作一个

database,这使得以图形化展示表与表之间外键关系这一功能受到了极

大影响,如果两个不同 schema 的表之间存在外键关联关系,那么在

Adminer 的界面上是无法展示出来的。如果你是 DBA,那么建议使用

pgAdmin,当然也可以安装一套 Adminer 以备不时之需。1.5 PostgreSQL数据库对象

假设你现在已经安装好了 PostgreSQL,请启动并连接好 pgAdmin,然后

点开左侧的目录树,此时展现在你面前的是一堆令人眼花缭乱的数据库

对象,有些你可能很熟悉,有些则可能闻所未闻。PostgreSQL 对象类型

的数量超过了绝大多数关系型数据库(这还是在未安装任何扩展包的情

况下)。这些对象中,有许多你可能永远都不会用到,但如果你发现业

务上需要实现一种新的对象类型,那么一般来说你要实现的东西在那一

堆眼花缭乱的对象中已经有前人实现过了,所以只需要正确选用即可。

本书不会介绍 PostgreSQL 以标准方式安装完毕后所提供的所有对象类

型,因为 PostgreSQL 引入新特性的速度惊人,任何一本书都不可能全

面覆盖所有对象类型。因此我们仅讨论你有必要了解的那些对象类型。

database2

2database 一词含义宽泛,既可表示广义的数据库系统,又可以表示某些特定数据库系统中的

某一级数据存储单位,如表述不当极易给读者造成混淆。因此本书中会区别使用,表示广义的

数据库系统时,用中文“数据库”;表示狭义的数据存储单位时,用英文“database”。——译者

每个 PostgreSQL 服务可以包含多个独立的 database。

schema3

3数据库业界对于 schema 有多种译法:纲要、模式、方案,等等。但各种译法都不能准确直观

地表达出其原本的含义,即位于一个独立命名空间内的一组相关数据库对象的集合,因此前述

译法从来没有一种成为主流。一般业界人员都直接使用英文 schema。考虑到这个情况,为防

止初级用户理解困难,我们也按照业界习惯直接使用英文原名。——译者注

ANSI SQL 标准中对 schema 有着明确的定义,database 的下一层逻

辑结构就是 schema。如果把 database 比作一个国家,那么 schema 就是一些独立的州

(或者是省、府、辖区等,具体取决于各国的实际情况)。大多数对象

是隶属于某个 schema 的,然后 schema 又隶属于某个 database。在创建

一个新的 database 时,PostgreSQL 会自动为其创建一个名为 public 的

schema。如果未设置

search_path

变量(后续会介绍该变量的含

义),那么 PostgreSQL 会将你创建的所有对象默认放入 public schema

中。如果表的数量较少,这是没问题的,但如果你有几千张表,那么我

们还是建议你将它们分门别类放入不同的 schema 中。

任何一个数据库中,表都是最核心的对象类型。在

PostgreSQL

中,表首先属于某个 schema,而 schema 又属于某个 database,这样就

构成了一种三级存储结构。

PostgreSQL 的表支持两种很强大的功能。第一种是表继承,即一张

表可以有父表和子表。这种层次化的结构可以极大地简化数据库设计,

还可以为你省掉大量的重复查询代码。第二种是创建一张表的同时,系

统会自动为此表创建一种对应的自定义数据类型。

视图

大多数关系型数据库都支持视图。视图是基于表的一种抽象,通过

它可以实现一次性查询多张表,也可以实现通过复杂运算来构造出虚拟

字段。视图一般是只读的,但 PostgreSQL 支持对视图数据进行修改,

前提是该视图基于单张实体表构建。如果需要修改基于多张表关联而来

的视图,可以针对视图编写触发器。9.3

版还引入了对物化视图的支

持,该机制通过对视图数据进行缓存来实现对常用查询的加速,缺点是

查到的数据可能不是最新的。更多细节请参见 7.1.3 节。扩展包

开发人员可以通过该机制将一组相关的函数、数据类型、数据类型

转换器、用户自定义索引、表以及属性变量等对象打包成一个功能扩展

包,该扩展包可以整体安装和删除。扩展包在概念上与

Oracle

package 类似,从 PostgreSQL 9.1 版本之后一般推荐使用该机制来为数

据库提供功能扩展。扩展包的具体安装步骤,请参考开发手册。一般来

说,需要先将扩展包的二进制安装包和脚本复制到 PostgreSQL 安装目

录下,然后运行一系列脚本,再在需要其功能的 database 中单独安装该

扩展包。注意:仅需在需要该扩展包功能的 database 中安装,不必为当

前数据库系统中的每个 database 都安装。比如需要对某个 database 中的

数据进行高级文本搜索,那么单独在该

database

中安装

fuzzystrmatch 扩展包即可。

安装扩展包时可以指定该包中所含有的成员对象安装到哪个

schema,若不指定则默认会安装到 public schema 中。我们不建议采用

默认设置,因为这会导致 public schema 变得庞大复杂且难以管理,尤

其是如果你将自己的数据库对象也都存入 public schema 中,那么情况

会变得更糟糕。我们建议你创建一个独立的 schema 用于存放所有扩展

包的对象,甚至为规模较大的扩展包单独创建一个 schema。为避免出

现找不到新增扩展包对象的问题,请将这些新增的 schema 名称加入

search_path 变量中,这样就可以直接使用扩展包的功能而无须关注

它到底安装到了哪个 schema 中。也有一些扩展包明确要求必须安装到

某个 schema 下(特别是过程式语言扩展包),这种情况下你就不能自

行指定了。有很多语言扩展包,比如

plv8,就要求必须安装到

pg_catalog schema 中。

多个扩展包之间可能存在依赖关系。在 PostgreSQL 9.6 之前,你需

要了解这个依赖关系并把被依赖包先装好,但从 9.6 版开始,只需在安装时加上 cascade 关键字,PostgreSQL 就会自动安装当前扩展包所依

赖的扩展包。例如:

CREATE EXTENSION postgis_tiger_geocoder CASCADE;

这条命令会先寻找并安装被依赖的 postgis 和 fuzzystrmatch 这

两个扩展包,当然,如果原本就有了,就不需要了。

函数

用户可以编写自定义函数来对数据进行新增、修改、删除和复杂计

算等操作,可以使用 PostgreSQL 所支持的各种过程式语言来编码。

PostgreSQL

装好以后自身就包含了数以千计的系统函数,都在默认的

postgres

库中。函数支持返回以下数据类型:标量值(也就是单个

值)、数组、单条记录以及记录集。其他数据库将对数据进行增删改操

作的函数称为“存储过程”,把不进行增删改的函数叫作“函数”,但

PostgreSQL 中并不区分,统一把二者称为“函数”。

内置编程语言

函数是以过程式语言编写的。PostgreSQL 默认支持三种内置编程语

言:SQL、PL/pgSQL 以及 C 语言。可以通过 CREATE EXTENSION 或者

CREATE PRODCEDURAL LANGUAGE 命令来添加其他语言。目前较常用的

语言是 PL/Python、PL/V8(即 JavaScript)以及 PL/R。我们将在第 8 章

中展示大量的相关示例。

运算符

运算符本质上是以简单符号形式呈现的函数别名,例如 =、&& 等。

PostgreSQL 支持自定义运算符。如果用户定义了自己的数据类型,那么

一般来说需要再自定义一些运算符来与之配合工作。比如你定义了一个复数类型,那么你很有可能需要自定义 +、-、*、/ 这几个运算符来对

复数进行运算。

外部表和外部数据封装器

外部表是一些虚拟表,通过它们可以直接在本地数据库中访问来自

外部数据源的数据。只要数据映射关系配置正确,外部表的用法就与普

通表没有任何区别。外部表支持映射到以下类型的数据源:CSV 文件、

另一个服务器上的 PostgreSQL 表、SQL Server 或 Oracle 这些异构数据

库中的表、Redis 这样的 NoSQL 数据库,甚至像 Twitter 或 Salesforce

这样的 Web 服务。

外部表映射关系的建立是通过配置外部数据封装器(foreign

data

wrapper,FDW)实现的。FDW 是 PostgreSQL 和外部数据源之间的一

架“魔法桥”,可实现两边数据的互联互通。其内部实现机制遵循

SQL

标准中的 MED(Management of External Data)规范,更多细节请参考

维基百科上关于 MED 的描述。

许多无私的开发者已经为当下大部分流行的数据源开发了 FDW 并

已免费共享出来。你也可以通过创建自己的 FDW 来练习。(我们建议

你一旦成功了也公布出来,这样整个社区都可以分享你的劳动成果。)

FDW 是通过扩展包机制实现的,安装好以后在 pgAdmin 界面上名为

Foreign Data Wrapper 的目录节点下能看到它。

触发器和触发器函数

绝大多数企业级数据库都支持触发器机制,该机制可以侦测到数据

修改事件的发生。在 PostgreSQL 中,当一个触发器被触发后,系统会

自动调用用户定义好的触发器函数。触发器的触发时机是可设置的,可

以是语句级触发或者记录级触发,也可以是修改前触发或修改后触发。在 pgAdmin 中,如果希望了解哪些表上挂载了触发器,只需在对

象树上层层点击,一直打开到表这一级,然后可以看到下面有个 trigger

子栏目,里面就是该表的所有触发器。

定义触发器时需要定义对应的触发器函数,这类函数与前面介绍过

的普通函数有所不同,主要差异在于触发器函数可以通过系统内置变量

来同时访问到修改前和修改后的数据,这样就可以实现对于非法的数据

修改行为的识别和拦截。因此触发器函数一般会用于编写复杂校验逻

辑,这类复杂逻辑通过 check 约束是无法实现的。

PostgreSQL 的触发器技术正在快速的演进之中。9.0 版引入了对

WITH 子句的支持,通过它可以实现带条件的记录级触发,即只有当某

条记录符合指定的 WHEN 条件时,触发器才会被调用。9.0 版还引入了

UPDATE OF 子句,通过它可以实现精确到字段级的触发条件设置。仅当

指定的字段内容被更改时才会激活触发器。9.1 版支持了针对视图的触

发器。9.3 版支持了针对 DDL 的触发器。目前支持触发器的 DDL 命令

列表请参见官方手册中“触发器触发时机一览表”。pgAdmin

中会把

DDL 触发器列在 event trigger 这一栏下。最后值得一提的是,从 9.4 版

开始,针对外部表的触发器也获得了支持。

catalog

catalog 的译法与 schema 存在相同的问题,翻译为“目录”后并不能让读者准确地理解其原意,

反而容易造成混淆,因此还是沿用英文原名。——译者注

catalog 是系统级的 schema,用于存储系统函数和系统元数据。每

database

创建好以后默认都会含有两个

catalog:一个名为

pg_catalog,用于存储 PostgreSQL 系统自带的函数、表、系统视图、

数据类型转换器以及数据类型定义等元数据;另一个是

information_schema,用于存储 ANSI 标准中所要求提供的元数据查

4

4询视图,这些视图遵从 ANSI SQL 标准的要求,以指定的格式向外界提

供 PostgreSQL 元数据信息。

一直以来,PostgreSQL 数据库的发展都严格地遵循着其“自由与开

放”的核心理念。如果你足够了解这款数据库,会发现它几乎是一种可

以“自我生长”的数据库。比如,它所有的核心设置都保存在系统表中,

用户可以不受限地查看和修改这些数据,这为 PostgreSQL 提供了远超

任何一种商业数据库的巨大灵活性(不过从另一个角度看,将这种灵活

性称为“可破坏性”也未尝不可)。只要仔细地研究一下 pg_catalog,

你就可以了解到 PostgreSQL 这样一个庞大的系统是如何基于各种部件

构建起来的。如果你有超级用户权限,那么可以直接修改 pg_catalog

的内容(当然,如果改得不对,那你的行为就跟搞破坏没什么两样

了)。

Information_schema catalog 在 MySQL 和 SQL Server 中也有。

PostgreSQL 的 Information_schema 中最常用的视图一般有以下几

个:columns 视图,列出了数据库中的所有字段; tables 视图,列出

了数据库中的所有表(包括视图);views 视图,列出了所有视图以及

用于创建该视图的原始 SQL。

类型

类型是数据类型的简称。每种数据库产品和每种编程语言都会支持

一系列的数据类型,比如整型、字符型、数组、二进制大对象(blob)

等。除前述常见类型外,PostgreSQL 还支持复合数据类型,这种类型可

以是多种数据类型的一个组合,比如复数、极坐标、向量、张量等都是

复合数据类型。

PostgreSQL 会自动为用户自己创建的表定义一个同名的复合数据类

型。这样就可以把表记录当作对象实例来处理。当用户需要在函数中遍历表记录时,该特性特别注意:在 pgAdmin 的界面上你看不到

这些在创建表时自动生成的自定义类型,但请放心,这并不代表它们不

存在。

全文检索

全文检索(full text search,FTS)是一种基于自然语言的搜索机

制。这种搜索机制有一些“智能”成分。与正则表达式搜索不同,全文检

索能够基于语义来进行匹配查找,而不仅仅是纯粹的语法匹配。例如,

用户需要在一段长文本中搜索 running 这个词,那么命中的结果可能包

含 run、running、jog、sprint、dash 等词。全文检索功能依赖于 FTS 配

置库、FTS 词典、FTS 解析器这三个部件。有了它们,PostgreSQL 原生

的 FTS 功能即可正常使用。一般场景下的全文检索靠这三个原生部件

已经足够,但在涉及药理学、有组织犯罪学等专业场景下,搜索目标文

本中会包括该领域专有词汇和特殊语法规则,此时需要用专门的

FTS

部件来替换原生 FTS 部件。我们会在 5.8 节探讨 FTS 功能。

数据类型转换器

数据类型转换器可以将一种数据类型转换为另一种,其底层通过调

用转换函数来实现真正的转换逻辑。PostgreSQL 支持用户自定义转换器

或者重载、加强默认的转换器。例如,如果你需要把邮政编码(美国的

邮政编码是一个 5 位的整数)从 integer 转换为 character,那么可

以自定义一个支持“数字不足 5 位则前面自动补 0”规则的转换器。

转换器可以被隐式调用也可以被显式调用。隐式转换是系统自动执

行的,一般来说,将一种特定数据类型转为更通用的数据类型(比如数

字转换为字符串)时就会发生隐式类型转换。如果进行隐式转换时系统

找不到合适的转换器,你就必须显式执行转换动作。序列号生成器

序列号生成器用于实现 serial 数据类型值的自动递增分配。在创

建 serial 字段时,PostgreSQL 会自动为其创建一个相应的序列号生成

器,但用户也可以很方便地更改其初始值、步长和下一个值。因为序列

号生成器是独立对象,所以多个表可以共享同一个序列号生成器。基于

该机制,用户可以实现跨越多个表的唯一键。SQL Server 和 Oracle 也都

支持序列号生成器,但必须手动创建。

规则

规则的功能是在一个 SQL 执行前对其进行改写。本书中不会讨论

有关规则的内容,因为这一技术已经过时,通过触发器能实现相同的功

能。

PostgreSQL 允许用户对前述每一种对象进行参数配置。这些参数可以在

服务级、库级、函数级等不同层级生效。你将来很可能会看到一个很炫

的词叫 GUC,意思是“大一统配置”(grand unified configuration),它

实际上指的就是 PostgreSQL 中的那些配置参数。1.6 最新版本的PostgreSQL中引入的新特性

PostgreSQL 在每年的 9 月份会发布一个大版本。每个新版本都会带来稳

定性、安全性、性能等方面的提升,以及一些前沿的新特性。而且版本

升级过程也变得越来越简单。那么显而易见,请尽量把你的数据库及时

升级到最新的稳定版。关于每个版本引入的关键特性列表,请参见官方

提供的“PostgreSQL 各版本功能特性一览表”。

1.6.1 为什么要升级

如果你正在使用 PostgreSQL 9.1 或者更早的版本,请立即升级!因为

9.1 版在 2016 年 9 月已进入生命周期终结(end of life,EOL)状态。请

参考 PostgreSQL 官方的发行版支持策略以获取更多关于 PostgreSQL

EOL 政策的细节。请务必不要使用已过了 EOL 期限的版本,因为开发

组不会再为其提供新的安全更新和功能补丁。一旦这种老版本出了问

题,你只能花钱去请 PostgreSQL 专家级顾问来解决故障或寻找临时解

决方案,这种服务一般都是很昂贵的,而且你不一定能找得到这种专

家。

不管当前使用的是哪个大版本,你都应该尽快跟进小版本号的更新。比

如从 9.1.17 升级到 9.1.21,只需要替换二进制文件并重启一下即可。小

版本仅修改 bug 而不会涉及功能变化,因此这种升级是很安全的,也会

为你降低出问题的概率。

1.6.2 PostgreSQL 10中引入的新特性

PostgreSQL 10 是目前最新的稳定版,于 2017 年 10 月发布。从

PostgreSQL 10 开始,PostgreSQL 会以一种新的方式升级其版本号。在

之前的版本中,发布大版本时变化的是第二位小版本号,比如从PostgreSQL 9.5 到 PostgreSQL 9.6,即使增加了一些比较大的新功能,

也只有小版本号发生变化。但从 PostgreSQL 10 开始,每个变化较大的

版本都会在主版本号上加一。因此 PostgreSQL 10 的下一个大版本是

PostgreSQL 11。这样就与 SQLite、SQL Server、Oracle 等数据库的版本

号策略保持了一致。

以下是 PostgreSQL 10 中引入的关键新特性。

提升了查询的并行度

对于并行查询启用了新的优化策略,包括并行位图堆扫描、并行索

引扫描等。这些增强将使得更多查询语句能被并行执行。请参考 9.4 节

以了解更多信息。

逻辑复制

此前版本的 PostgreSQL 中已经支持流复制特性。通过流复制可以

实现整个 PostgreSQL 服务实例的复制,但该机制有一些固有的缺点:

从节点是只读的,只能用于数据查询,不能对其数据进行修改;从节点

上也不能创建自己独有的表。逻辑复制解决了这两个问题。通过逻辑复

制可以实现仅复制单张表或者单个 database(不用复制整个服务实例的

所有数据)。既然不需要复制整个数据库服务,那么自然从库上就可以

有自己的表和数据,这部分数据是不包含在复制体系中的,因此主从库

上允许不一样。

针对 JSON JSONB 类型的全文检索

此前的版本中,to_tsvector 函数仅能为文本类型的字段生成全

文检索向量。现在它已支持处理 JSON 和 JSONB 类型,处理过程中会

忽略其中 key 的部分,而仅包含 value 的部分。同时 ts_headline 函数

也专为 JSON 和 JSONB 类型做了适配,它可以对 JSON 内容中的关键字进行加亮标记。详情请参考 5.8.7 节。

支持 ANSI 标准中的 XMLTABLE 特性

XMLTABLE 特性可以将 XML 文本内容以一种更为简单的方式映射

为普通二维表记录。该特性在 Oracle 和 IBM DB2 中已支持。详情请参

见示例 5-41。

FDW 聚合下推

FDW API 可以将 COUNT(*) 或者 SUM(*) 这种聚合操作推送到远端

节点执行。postgres_fdw

插件从该特性中受益最大。此前的版本

中,postgres_fdw 插件在执行聚合操作时,需要把所有相关数据从远

端 PostgreSQL 取到本地然后再进行聚合运算,这极大地影响了整体运

算效率。

声明式表分区

此前的版本中,实现分区表功能需要借助表继承机制。表继承机制

的问题在于,用户需要自行编写触发器来实现把数据分流到子表中的过

程。PostgreSQL 10 引入了 PARTITION BY 语法,利用该语法,用户只

需在创建表时附加 PARTITION BY 子句就可以自动实现表分区。此后向

父表插入数据时,数据会被分流到子表中,这一切都是自动的,无须用

户预先创建触发器。请参考 6.1.3 节以了解详情。

查询性能优化

该版本中对查询性能实现了多方面的优化。

支持创建多字段统计信息CREATE STATISTICS 命令支持针对多个字段建立统计信息。具体

请参见示例 9-18。

支持 IDENTITY 数据类型

新增支持 IDENTITY 自增字段类型,创建表和修改表结构时都可以

使用。增加该类型是为了在设计表的自增字段时更加符合业界通行做

法。具体请参见示例 6-2。

1.6.3 PostgreSQL 9.6中引入的新特性

PostgreSQL 9.6 发布于 2016 年 9 月,是 9.x 系列中的最新版本。

支持并行查询

9.6 版之前,PostgreSQL 并不能充分地利用系统中的多核能力。9.6

版中,PostgreSQL 引擎能够将一些特定类型的查询语句放到多个处理器

核心上并行执行。支持并行执行的操作有:顺序扫描、部分 join 以及部

分聚合操作。然而,增删改这些修改数据的操作无法实现并行。支持并

行化的工作还在进行中,最终目标是所有的语句都能利用到多核并行执

行。详情参见 9.4 节。

支持关联词组全文检索

全文检索支持关联词组搜索,可以使用 <-> 运算符来表示两个关联

词之间的距离。即使关联词没有连在一起出现,只要二者出现的位置不

超出前述距离,也认为该关联词组搜索命中。在 9.6 之前的版本中,只

能搜索一些单个的词,但该功能使得用户可以搜索一组有前后顺序的词

组。详情请参见 5.8 节。

psql 工具支持 \gexec 参数该参数的功能是读取并执行一个根据查询语句动态生成的 SQL。详

情请参见 3.4.5 节。

postgres_fdw 增强

对于简单的更新、插入和删除来说,速度有很大提升。请参考博

文“Directly Modify Foreign Tables”以了解详情。

FDW 关联操作下推

包括 postgres_fdw 在内的部分 FDW 已支持该特性。当需要对多

张外表做关联查询时,之前的做法是把每张外表的数据取回本地然后做

关联计算,支持了该特性的 FDW 的优化处理方式是:如果需要关联的

两张外表都来自于同一台外部服务器,那么就把 join 操作下推到这个外

部服务器上去执行,然后仅把关联结果拿回来。这样可以极大地减少经

网络传输的记录数。当关联操作可以过滤掉大量数据时,这个特性带来

的性能提升是巨大的。

1.6.4 PostgreSQL 9.5中引入的新特性

PostgreSQL 9.5 发布于 2016 年 1 月,其主要的新特性如下。

外部表架构的改进

支持了新的 IMPORT FOREIGN SCHEMA 命令,通过该命令可以从外

部服务器中加载表结构信息从而实现批量创建外表。支持外表继承:本

地表可以继承自外表,外表也可以继承自本地表,外表也可以继承自另

一张外表。支持在外表上创建约束。详情请参见 10.3 节和 10.3.3 节。

支持无日志表直接升级为日志表由于无日志表不写日志,往其中导入数据时会很快,但缺点是数据

库崩溃时会完全丢失数据。在此前的版本中,当数据完全导入无日志表

后,要想把无日志表改为日志表需要创建一张新表,然后再把无日志表

的数据写入新表。9.5 版提供了一个新的语法:ALTER TABLE ... SET

UNLOGGED,可以直接把无日志表修改为日志表,这样就省去了重新建

表并搬迁数据的过程。

array_agg 函数支持数组入参

array_agg 函数可以将某字段的多条记录聚合为一个数组。在 9.5

版之前,入参字段类型不能是一个数组,但 9.5 版之后支持输入数组入

参,这样就可以构造出多维数组。详情请参见示例 5-17。

支持 BRIN 索引类型

BRIN(block range index)是一种新型的索引,相比 B-树和 GIN 索

引有着更小的内存占用。有些情况下 BRIN 索引会比前述两种索引速度

更快。详情请参见 6.3 节。

支持 GROUPING SETSROLLUP CUBE 聚合语法

该特性用于聚合查询语句中,可以实现一次性获取多维度汇聚结

果。具体例子请参见 7.7 节。

仅索引扫描

如果要查询的字段在索引中已经全部包含,则仅扫描索引即可获得

查询结果,而不用访问表数据,这种查询模式称为“仅索引扫描”。当前

只有 GiST 索引支持此特性。

支持无则插入有则更新处理(即 UPSERT 能力)9.5

版之前,如果插入或者更新操作违反了主键约束或者其他约

束,那么该操作会失败。9.5 版提供了一种机制,允许用户捕获该异常

并自定义替代操作或者跳过引发问题的记录。详情请参见 7.2.11 节。

支持跳过无法写锁定的记录

如果用户希望锁定一些记录以用于后续更新,那么可以使用

SELECT ... FOR UPDATE 来锁定这些记录。在 9.5 版之前,如果试图

锁定的部分或者全部记录已被其他用户锁定,那么当前用户的锁定操作

就会报错。9.5 版中提供了一个 SKIP LOCKED 子句语法,可以跳过那些

已经被别人锁定的记录,这样就不会报错。

行级安全控制

支持对用户设置记录级的读写权限,即同一张表中,部分记录只允

许某个用户读写,另外一部分记录只允许另外一个用户读写。在多租户

场景下,显然该功能是特别有用的;对于需要进行访问权限隔离而又无

法通过分表实现的场景,该功能也特别有价值。

1.6.5 PostgreSQL 9.4中引入的新特性

9.4 版发布于 2014 年 9 月,主要包含以下新特性。

物化视图特性的改进

在 9.3 版中,刷新物化视图期间会对其加锁并禁止访问,而加锁时

间可能会比较长,这直接导致在生产环境中物化视图的实用价值严重受

限。9.4 版中取消了刷新时的加锁动作,因此即使是正在被刷新的物化

视图也可被访问。但请注意:利用此特性的前提是物化视图必须拥有一

个唯一索引。新增支持用于计算百分比的分析函数

新增了对

percentile_disc(不连续百分比)和

percentile_cont(连续百分比)这两个分析函数的支持,须配合

WITHIN GROUP (ORDER BY...) 子句使用。PostgreSQL 专家 Hubert

Lubaczewski 在文章“Ordered Set Within Group Aggregates”中介绍了

ORDERED SET WITHIN GROUP 聚合运算。在 9.5 之前的版本中,

PostgreSQL 并未提供过计算中位数的函数。这是有原因的。如果你对计

算中位数的相关算法有所了解的话,应该知道这种算法中最后都会有一

个额外的类似于“平局加时赛”的计算步骤,这个步骤的存在使得将中位

数算法实现为聚合函数非常困难。9.5 版中引入的这两个分析函数使用

了一种快速中位数估算算法,从而绕开了前述问题。我们将在 7.2.16 节

对这两个函数进行更深入的介绍。

支持对视图更新操作的结果范围进行限制

创建视图时支持 WITH CHECK OPTION 子句,其作用是确保在视图

上执行更新或者插入操作时,修改后或者新插入的记录仍然在本视图可

见范围内。详情请参见示例 7-3。

新增对 JSONB 数据类型的支持

该数据类型是 JSON(JavaScript Object Notation)类型的二进制存

储版本。通过 JSONB 类型可以对 JSON 格式的文档数据建立索引,并

可加快对其内部元素的访问速度。详细信息请参考 5.6 节,同时可参考

这两篇博客文章:“Introduce jsonb: A Structured Format for Storing

JSON”以及“JSONB: Wildcard Query”。

GIN 索引改进GIN

索引在设计时已经考虑了要适用于全文搜索、三连词处

理、hstore 键值数据库以及 jsonb 类型支持等场景。在很多情况下你

甚至可以把它当作 B-树索引的替代品,一般来说 GIN 索引与 B-树的查

找效率相当,但占用空间更少。9.5 版中,GIN 索引的查询速度被进一

步提升。详情请参见“GIN as a Substitute for Bitmap Indexes”这篇文章的

介绍。

支持更多 JSON 函数

具体包括

json_build_array、json_build_object、json_object、json_to_record

和 json_to_recordset 等几个函数。

加速跨表空间的对象搬迁

支持使用以下语法轻松地将所有数据库对象从一个表空间移动到另

一个表空间:ALTER TABLESPACE old_space MOVE ALL TO

new_space;。

支持对返回的结果集中的记录加上数字编号

现在可以为查询结果中的记录添加行号。行号用系统字段

ordinality(该字段是在 ANSI SQL 标准中定义的)表示。当需要将

存储为数组、hstore 键值对或者复合类型的非格式化数据转换为格式

化记录时,该功能特别有用。以下是一个使用 hstore 的例子:

SELECT ordinality, key, value

FROM each('breed=>pug,cuteness=>high'::hstore) WITH ordinality;

支持通过执行 SQL 命令来更改系统配置设置利用 ALTER system SET ... 语法,无须修改 postgresql.conf 文件

即可设置全局系统配置。postgresql.conf

文件具体的修改方法请参见

2.1.2

节。这也意味着用户可以通过编程的方式动态地调整系统配置

项,但请注意:有的配置项修改后需要重启数据库才能生效。

触发器功能增强

9.4 版中支持了对外部表创建触发器。

数据行转列能力增强

unnest 函数用于实现数据的行转列操作,即将一个横向的数组转

换为纵向的一个字段的多行记录。该函数可接受多个数组作为入参,每

个数组转换后成为单独的一列,即输入几个数组转换后就有几列。如果

每个数组的元素个数不一样,9.4 版之前转换后的结果是不可预知的,

9.4

版本后这种情况下转换的结果是可预知的,会以最长的数组为标

准,其他不足此长度的数组元素补 null。

新增 ROWS FROM 语法

该语法可以将多个函数返回的结果集逐行拼接起来,最后作为一个

完整的结果集返回,因此即使这些结果集之间的元素个数不一致也没关

系,如下例所示:

SELECT *

FROM ROWS FROM (jsonb_each('{"a":"foo1","b":"bar"}'::jsonb),

jsonb_each('{"c":"foo2"}'::jsonb))

x (a1,a1_val,a2_val);

支持动态启用后台工作线程

当使用 SQL 或 PostgreSQL 函数都无法实现所需要的功能时,可以使用 C 语言编码实现动态后台工作线程来达成目标。9.4 版源码的

contrib/worker_spi 目录下实现了一个小型的示例,可供参考。1.7 数据库驱动程序

任何情况下,你都不可能脱离具体的业务系统而仅仅使用 PostgreSQL

数据库本身,那显然是无意义的。为了实现 PostgreSQL 与业务系统之

间的交互,就需要借助数据库驱动程序。PostgreSQL 拥有大量免费驱

动,支持各种编程语言和开发工具。此外,很多商业公司也以很低廉的

价格提供了各有特色的驱动。目前比较流行的几种开源驱动如下。

PHP 驱动:PHP 语言广泛应用于 Web 开发领域,大多数 PHP 发行

包都自带了较老的 pgsql 驱动或者是较新的 pdo_pgsql 驱动。一般

来说这两种驱动默认都会安装,不过可能需要修改 php.ini 来决定

启用哪一种。

JDBC 驱动:Java 开发所使用的 JDBC 驱动一直是与最新版

PostgreSQL 同步更新的,可以从 PostgreSQL 官方站点下载。

.NET 驱动:.NET 框架(含微软的官方版和 Mono 社区的开源版)

可使用 Npgsql 驱动。目前该驱动支持微软 .NET 框架,包括微软

Entity Framework 开发框架以及 Mono 开源 .NET 框架。

ODBC 驱动:如果需要从微软 Access、Excel 或者其他支持 ODBC

的产品连接到 PostgreSQL,可从 PostgreSQL 官网下载 ODBC 驱

动,支持 32 位和 64 位两个版本。

LibreOffice/OpenOffice 驱动:LibreOffice 3.5 及之后的版本中自带

了 PostgreSQL 驱动,但 3.5 之前的版本以及 OpenOffice 是不带

的,可以使用 JDBC 或者 SDBC 驱动。更多细节请参见“OO Base

and PostgreSQL”这篇博文。

Python 驱动:Python 可通过多种驱动访问 PostgreSQL,目前

psycopg2

是最流行的一种。Python

Django

开发框架对

PostgreSQL 也有着良好的支持。如果你需要一个关系 - 对象映射工

具(即通常所说的 ORM 工具),可以考虑使用最广泛的 SQLAlchemy 工具,著名的外部数据源封装器开发平台 Multicorn 内部

就使用了它。

Ruby 驱动:对 Ruby 开发人员来说,请使用 rubygems pg 驱动。

Perl 驱动:Perl 可以使用 DBI 和 DBD::Pg 驱动。也可以使用由

CPAN 网站提供的 DBD::PgPP 驱动。

Node.js 驱动:Node.js 是一个 JavaScript 框架,可用于构建可扩展

的网络应用。该平台目前支持两种 PostgreSQL 驱动:一种是 Node

Postgres,该驱动可以选择是否绑定本地

libpq

库,而且基于纯

JavaScript(无须编译);另一种是 Node-DBI。1.8 如何获得帮助

在使用 PostgreSQL 的过程中,你迟早会需要寻求帮助,而且这一天往

往会比预期来得早。我们希望你能够尽早了解到求助的途径。我们最为

推荐的途径是邮件列表,不管你是 PostgreSQL 的新用户还是老用户,

邮件列表都能为你解答技术问题。可以先打开 PostgreSQL 邮件列表页

面。如果你是新手,那么订阅 PGSQL-General 这个邮件列表是最合适

的。如果你认为自己发现了 PostgreSQL 的 bug,那么打开“PostgreSQL

故障报告”这个页面,上面会告诉你具体如何操作1.9 PostgreSQL的主要衍生版本

PostgreSQL 使用了 MIT/BSD 风格的许可证,任何人都可以合法地对其

修改并二次传播,因此对于那些想创建自己数据库分支的人来说,

PostgreSQL 是绝佳的选择。在过去的很多年间,有很多团队创建了自己

的 PostgreSQL 分支版本,并且对社区也做出了相应的回馈,有的把自

己的修改贡献回了 PostgreSQL 的主干代码,有的对社区给予了资金支

持。访问
https://wiki.postgresql.org/wiki/PostgreSQL_derived_databases 这

个地址,就可以看到 PostgreSQL 数据库的所有衍生产品。

很多流行的分支版本是商业化的闭源软件。比如目前数据仓库领域使用

很广泛的 Netezza 就是源自 PostgreSQL。亚马逊公司的 Redshift 数据仓

库事实上是 PostgreSQL 的一个分支的分支。亚马逊还有其他两个与原

生 PostgreSQL 血缘关系较近的产品:Amazon RDS for PostgreSQL 和

Amazon Aurora for PostgreSQL。这两个产品会与 PostgreSQL 开源版本

的主干代码保持同源,并确保与原生 PostgreSQL 提供完全相同的 SQL

语法,同时额外提供了更强的管理功能并在速度方面做了一些优化。

EnterpriseDB 公司推出的 PostgreSQL Advanced Plus 也是以 PostgreSQL

为基础,另外增加了对于 Oracle 语法和特性的兼容支持,以吸引原

Oracle 用户。EnterpriseDB 公司向 PostgreSQL 社区提供了资金和开发力

量的支持,对此我们表示感谢。他们的 Postgres Plus Advanced Server 产

品在版本更新节奏上也一直是密切跟进最新的 PostgreSQL 稳定版的。

Postgre-X2、Postgres-XL

GreenPlum

是三款还处于发展初期的

PostgreSQL 开源衍生产品,其中 GreenPlum 曾经有一段时间是闭源的。

这三款产品的目标都是处理大规模数据分析和复制工作。

PostgreSQL 之所以衍生版本众多,部分原因是主干版本对于一些小众的需求可能不会及时支持,另外主干版本的发布节奏也不能满足所有人的

要求,那么自己拉出来一个分支版本提前进行修改和测试就是更好的选

择。很多这种分支版本中开发出来的新特性最终都汇合到了主干,比如

2nd Quadrant 公司支持多主和双向复制特性的 BDR 产品分支中的逻辑

复制功能就被汇合入了主干,用于强化 PostgreSQL 原生的复制功能。

PostgreSQL-XL 中开发的一些并行化特性将来也可能会合入 PostgreSQL

主干中。

Citus 是一个支持实时大数据处理和并行查询功能的 PostgreSQL 分支,

从 PostgreSQL 9.5 开始它被改造成了 PostgreSQL 的一个扩展包,使用

起来更加方便。

Google 最近发布了它的 Google Cloud SQL for PostgreSQL 产品,目前还

处在 beta 测试阶段。