PostgreSQL

PostgreSQL（ˌ POHST）是一款功能全面且开源的关系型数据库管理系统，凭借其卓越的扩展能力和对SQL标准的严格遵循而广受赞誉。作为一款成熟的数据库系统，它不仅支持符合ACID特性的事务处理，还集成了自动更新的视图、物化视图、触发器、外键约束以及存储过程等一系列强大功能。

PostgreSQL能够在Windows、Linux、macOS等主流操作系统上流畅运行，其应用范围极为广泛，无论是单机应用、大规模数据仓库，还是数据湖、高并发Web服务等场景，都能应对自如。

PostgreSQL的核心开发工作由全球开发组（PostgreSQL Global Development Group）负责，他们专注于数据库引擎及其核心组件的研发与优化。在这个核心团队之外，还活跃着一个生机勃勃的开发者社区和生态系统，他们为PostgreSQL提供了众多增强功能，填补了通常由商业数据库供应商所提供的功能空缺。这些扩展涵盖了地理空间数据处理、时序数据库支持等特殊领域，以及模拟其他数据库产品的兼容层。

同时，第三方开发者也贡献了各种用户和机器接口功能，包括图形用户界面、负载均衡和高可用性工具集等。

尽管这个庞大的支持网络（涵盖个人、企业、产品和项目）并非PostgreSQL开发组的一部分，但它们共同促进了PostgreSQL生态系统的繁荣发展，对数据库的推广与应用起到了至关重要的作用。

这款数据库系统最初名为POSTGRES，以彰显其作为加州大学柏克莱分校Ingres数据库系统继承者的身份。1996年，为了体现其对SQL的支持，项目更名为PostgreSQL。经过2007年的一次评审，开发团队决定保留PostgreSQL这个名称和Postgres这个简称。

## 历史

PostgreSQL经历了长时间的演变。该项目最初始于加利福尼亚大学伯克利分校的Ingres计划。这个计划的领导者迈克尔·斯通布雷克在1982年离开加利福尼亚大学伯克利分校以推动Ingres的商业化，但最后还是返回了学术界。在1985年返回伯克利之后，斯通布雷克开始了post-Ingres计划，致力于解决1980年代早期数据库系统所存在的一些问题。Postgres和Ingres的代码库自始至终保持完全分离。

新项目Postgres的目的是通过引入最少量的必要功能，以完整支持所需要的类型。这些功能包括类型定义和完整描述数据关系的能力。完整描述数据关系的能力先前虽已广泛使用，但仍需要由用户自行维护。Postgres的数据库能够“理解”关系，并可以通过特定规则，以自然的方式在相关的表中检索信息。

从1986年开始，该项目组发表了一些描述这一系统基本原理的论文，并在1988年实现并运行了一个Demo版本。项目组在1989年六月向少数用户发行了版本1.0，随后在1990年6月发行了带有全新规则系统的版本2.0。1991年的版本3.0再次重写了规则系统，并增加了对多个存储管理器的支持与改进的查询引擎。Postgres在1993年开始拥有大量用户，这些用户提供了大量的功能与优化建议。但是在发行了作为细节修正的版本4.0之后，Postgres计划就终止了。

尽管Postgres计划正式的终止了，BSD许可证（Postgres遵守BSD许可证发行）却使开发者们得以获取源代码并进一步开发系统。1994年，两个加利福尼亚大学伯克利分校的研究生 Andrew Yu和Jolly Chen 增加了一个SQL语言解释器来替代早先的基于Ingres的QUEL系统，建立了Postgres95。代码随后被发布到互联网上供全世界使用。Postgres95在1996年被重命名为PostgreSQL以便突出该数据库全新的SQL查询语言。

PostgreSQL首次发行即选择6.0作为其版本号，由来自世界各地的数据库开发者和志愿者们，通过互联网进行软件的维护。在2005年1月19日，PostgreSQL发行了版本8.0。自版本8.0之后，PostgreSQL得以借助原生方式运行于Windows系统之下。

尽管许可证允许PostgreSQL被用于商业用途，PostgreSQL却并没有像Ingres那样快速的被商业化。在2005年1月，PostgreSQL才收到了它来自数据库厂商的第一份援助。Pervasive Software宣布了对PostgreSQL的商业支持和社区参与。

但其实在此之前，就已经有一些公司开始对PostgreSQL伸出援手。2000年，前Red Hat投资者筹组了一间名为Great Bridge的公司来商业化PostgreSQL，与其他商用数据库厂商展开竞争。Great Bridge资助了好几位PostgreSQL开发者，并且贡献了许多资源给社区。然而到了2001年末，Great Bridge却终止了营运，一部分原因在于PostgreSQL在被商业化后，其市场状况并不理想。

2001年，Command Prompt, Inc.发布了Mammoth PostgreSQL，这是最老牌的PostgreSQL商业软件。他们通过对开发者的赞助，和开发PL/Perl、PL/php等PostgreSQL在各语言中的实现，以及维护PostgreSQL Build Farm等方式来支援PostgreSQL社群。

2005年1月，PostgreSQL接到了来自另一间数据库厂商Pervasive Software的支持，该公司以常见于Novell NetWare平台的Btrieve产品而闻名。他们宣布了进行商业支援和对社群的参与。但在他们成功商业化PostgreSQL一段时间后的2006年7月，Pervasive Software离开了PostgreSQL的支援市场。

在2005年中，两间其他的公司宣布商业化PostgreSQL，分别进入不同的利基市场。EnterpriseDB宣布将专注于让使用Oracle的应用程序能更容易的在PostgreSQL上运行。Greenplum则专注贡献在资料仓储和商业智慧的应用程序，尤其以BizGres专案著称。

2005年10月，昇阳的软件部门执行副总裁John Loiacono谈论到："我们不会去OEM微软的产品，我们正关注着PostgreSQL"，尽管当时并没有任何规格释出。到了2005年11月，昇阳宣布将支援PostgreSQL。2006年6月，Solaris 10包含PostgreSQL一起发布。

至于PostgreSQL专案本身，他继续着每年一个主要版本发布，以及次要的除错版本发布，这些发布全都遵守BSD授权。

## 描述

如果很粗略地观察PostgreSQL，会觉得这个数据库系统和其它数据库很类似。因为PostgreSQL使用SQL语言来执行资料的查询。这些资料通过外键联系在一起，以一系列表格的形式存在。PostgreSQL相对于竞争者的主要优势为可编程性：对于使用数据库资料的实际应用，PostgreSQL让开发与使用变得更简单。

SQL数据在“平面表格”中存储简单的数据类型，需要用户使用查询把有关的信息收集在一起。这与应用和用户利用数据自身的方式相对立：典型的使用带有丰富数据类型的高级语言，在其中所有有关的数据作为它自己的一个完整单元来操作。典型的称呼为记录或对象（依据各自语言）。

转换来自SQL世界的信息到面向对象编程世界体现得很困难，因为两者有非常不同的数据组织的模型。工业界把这个问题称为对象关系不匹配：从一个模型映射到另一个要花费项目开发者40%的时间。一些映射解决方案，典型的称为对象关系映射，致力于这个问题，但是它们花费很多并有自身的问题，导致糟糕的性能或强制所有的数据访问通过映射所支持的一种语言来进行。

PostgreSQL可以直接在数据库中解决很多这类问题。PostgreSQL允许用户定义基于正规的SQL类型的新类型，允许数据库自身理解复杂数据。例如，你可以定义一个`address`来组合一些事物如街道编号、城市和国度的字符串。从这一点上你可以轻易地建立把保存地址所需要的所有字段包含在一个单一行列中的表。

PostgreSQL还允许类型包括继承，这是在面向对象编程中的主要概念。例如，你可以定义`post_code`类型，并接着基于它建立`us_zip_code`和`canadian_postal_code`。在数据库中的address就可以采用`us_address`或者`canadian_address`形式，而特定的规则可以在各自情况下验证数据。在PostgreSQL的早期版本中，实现新类型需要写C扩展并把它们编译到数据库服务器中；在版本7.4中，通过`CREATE DOMAIN`建立和使用定制类型变得很容易了。

数据库自身的编程可以从使用函数上获得巨大的利益。多数SQL系统允许用户写存储过程，它是其他SQL语句可以调用的一块SQL代码。但是SQL自身仍旧不适合作为编程语言，而且SQL用户在构造复杂逻辑时要经历巨大的困难。更糟糕的是，SQL自身不支持很多的编程语言中最基本的操作，比如分支和循环。每个厂商都转而写它们自己对SQL语言的扩展来增加这些特征，而这种扩展不是必须跨越数据库平台操作。

在PostgreSQL中程序员可以用一组可观的支持语言中任何一种来写这种逻辑。

- 类似于Oracle的过程语言PL/SQL的叫做PgSQL的内置语言，在处理查询密集的过程时提供了独特的优势。
- 流行脚本语言比如Perl、Python、Tcl和Ruby的包装器，允许利用它们在字符串处理和连接到广阔的外部函数库的力量。
- 需要把复杂逻辑编译到机器代码所能提供的高性能的过程可以利用C或C++。
- 在更加深奥的方面，R统计语言的处理器允许数据库查询利用它的一组丰富的统计函数。

程序员可以把代码作为函数插入服务器中，它是使代码类似于存储过程的一个小包装器。以这种方式SQL代码可以调用（比如）C代码或反之。

- 性能增进，因为数据库引擎在一个时间一个地方调用所有的逻辑，减少了在客户和服务器之间的来回往返的次数。
- 可靠性增进，因为数据验证代码集中到一个地方，就在服务器上，而不用依赖在多个客户应用中的同步逻辑，它们甚至可能以多种编程语言写成。
- 通过向服务器增加有用的抽象，客户代码可以变得更短小和简单。

这些优势合起来可以证实PostgreSQL从编程角度是最高级的数据库系统。使用PostgreSQL可以显著的减少很多项目的整体编程时间，这种优势随着项目复杂而增长。

## 特征

### 函数

通过函数，可以在数据库服务器端执行指令程序。尽管这样的指令程序可以使用基本的SQL语句写成，但是由于其缺乏流程控制等功能，所以在PostgreSQL中引入了使用其它程序语言编写函数的能力，包括：

- 一个内置的名为pgSQL的过程语言，类似于Oracle的PL/SQL。
- 包括PL/Perl，PL/PHP，PL/Python，PL/Ruby，PL/sh，PL/Tcl与PL/Scheme在内的脚本语言。
- 编译语言：C，C++，或Java（通过PL/Java）。
- R统计语言PL/R。

以上部分的语言，甚至可以在触发器内执行。PostgreSQL支持行返回函数：它们的输出是一系列行类型数据的集合，可以在查询中当作表来使用。函数也可以被定义成以创建者或者调用者的身份运行。在某些场合，或者其他的数据库产品中，函数也会被称为“存储过程”，但技术上这两者并未有太大分别。

### 索引

在PostgreSQL中，用户可以自定义索引方法，或使用内置的B树，哈希表与GiST索引。PostgreSQL的索引功能同时也具有以下功能：

- 反向索引检索：无须额外的索引就能实现类似`ORDER BY ''field'' DESC`的操作。
- 表达式索引：可以建立基于表达式值而非数值或列的索引。
- 部分索引：仅索引表的部分，可以通过在`CREATE INDEX`语句口添加`WHERE`从句以创建更小的索引。
- 位图索引扫描：从8.1版开始支持此功能。该功能将读取多个索引，生成表示它们之间符合查询标准的多元组交集的位图。这样解决了混合索引的问题。在一个具有20列的表中，理论上能创建20! 个索引，在实际应用中并不实用。使用位图索引扫描后，在每次查询时，它将能把约束条件中所涉及列各自的索引进行任意的排列组合。

### 触发器

触发器是由SQL语句查询所触发的事件。如：一个INSERT语句可能触发一个检查数据完整性的触发器。触发器通常由INSERT或UPDATE语句触发。

在PostgreSQL中，可在数据表上设置触发器，但无法在视图中设置(对视图的UPDATE或者INSERT操作可以使用规则（RULE）定义）。多个触发器可依据字母顺序依次执行。此外，除了使用内嵌的PL/PgSQL语言之外，触发器的函数也可以用PL/Perl，PL/Python等语言编写。

### 多版本并发控制

PostgreSQL使用多版本并发控制（MVCC，Multiversion concurrency control）系统进行并发控制，该系统向每个用户提供了一个数据库的“快照”，用户在事务内所作的每个修改，对于其他的用户都不可见，直到该事务成功提交。这从很大程度上减少了对读取锁的依赖，同时保证了数据库高效地符合ACID原则。

### 规则

规则（RULE）允许一个查询能被重写，通常用来实现对视图（VIEW）的操作，如插入（INSERT）、更新（UPDATE）、删除（DELETE）。

### 数据类型

PostgreSQL内置丰富的数据类型，包括：

- 任意精度的数值
- 无限制长度文本
- 几何图元
- IP地址与IPv6地址
- 无类域间路由地址块，MAC地址
- 数组
- JSON数据
- 枚举类型
- XML数据 (需要在PostgreSQL源码编译时指定 "--with-libxml"选项)

此外，用户可以创建自定义数据类型，通常通过PostgreSQL的GiST机制，它们也能被很好得索引，比如PostGIS地理信息系统的数据类型。

### 用户定义对象

用户可以为数据库内几乎所有的对象定义新的类型，包括：

- 索引
- 操作符（可重载现有操作符。）
- 聚合函数
- 数据域
- 数据类型转换
- 会话（编码转换）

### 继承

数据表的结构及属性可从一个“父”表中继承，数据将在两者间共享。对子表中数据的插入或者删除也将在父表中体现，同样，对父表作出的修改，比如添加列等操作也会导致子表产生相应的改动。该功能尚未完全实现，实际上，表的约束尚不能继承。比如，在一张外联参考了父表id字段的表中，插入一条具有子表中某条记录id数据的记录会导致失败，因为PostgreSQL在对父表的外键约束检查中不会检查子表的内容。

### 其他功能

- 关系完整性约束：包括外键，列约束与行检查
- 视图
- 内、外（全、左、右）连接
- 子查询
- 事务处理
- 支持大部分SQL:2003标准的主要特征。不支持部分特征，和将来支持的特征，可至已有版本手册中查询。
- SSL加密连接
- 二进制／文本大对象的存储
- 在线备份
- 数据域
- 表分区
- 表空间
- 保存点
- 时刻点恢复
- 二阶段提交
- TOAST（The Oversized-Attribute Storage Technique，超大属性存储技术）用以透明地将超大表属性（如大MIME附件或XML消息）压缩后存储至独立的区域
- 正则表达式

### 数据库管理及开发工具

- phpPgAdmin基于php语言写的用于管理PostgreSQL数据库的程序
- PgAdmin另外一个用于管理PostgreSQL数据库的软件

### 扩展

- 地理数据对象：PostGIS GPL
- 向量数据： pgvector
- 全文检索：通过Tsearch2GPL或OpenFTS，将在8.3版本中内嵌Tsearch2
- 多种异步主／从复制方案，包括Slony-I（BSD授权），Mammoth Replicator
- XML/XSLT支持contrib软件包中的XPath扩展GPL
- 机器学习：MADlibASF，由Apache基金会的支持的顶级开源项目；集成大量传统数学分析统计、图计算以及一些常见的机器学习的算法

## 知名客户

- .org域名库
- The American Chemical Society
- Chicagocrime.org
- Skype
- Penny Arcade
- IMDB
- Sony Online
- 美国劳工部
- Wisconsin Circuit Court Access with 6 * 180GB DBs replicated in real time
- OpenACS and .LRN
- Evergreen－一个开放源代码（GNU通用公共许可证）的集成图书馆系统
- GNU Health

## 版本

PostgreSQL - Red Hat Edition是由Red Hat制作的分支版本，又称Red Hat Database。

## 参阅

- 关系数据库管理系统
- 关系型数据库管理系统列表
- 关系型数据库管理系统对比
- 对象数据库管理系统
- 对象数据库管理系统列表
- 对象数据库管理系统对比

## 外部链接

- PostgreSQL国际官方网站
- PostgreSQL 台湾使用者社群
- PostgreSQL :：国际中文社群网志：:
- PostgreSQL文档
- SourceForge上PostgreSQL的相关项目
- PgFoundry-PostgreSQL相关项目网站
- Open Source Database Network
- Database Journal的PostgreSQL专栏
- PostgreSQL中文推广教学平台 - Mammoth

## 基本资料

- 开发者：PostgreSQL Global Development Group
- 状态：开发中
- 发行日期：1996年7月8日
- 操作系统：Linux, Windows, FreeBSD, OpenBSD, NetBSD, macOS, AIX, HP/UX, Solaris 等
- 平台：x86, x86_64, IA64, PowerPC, PowerPC 64, S/390, S/390x, Sparc, Sparc 64, ARM, MIPS, MIPSEL, PA-RISC 等
- 编程语言：C语言
- 语言：英语
- 类型：关联式数据库
- 许可协议：PostgreSQL授权