Postgres

**PostgreSQL** 是一個開源的物件 - 關聯式資料庫管理系統，在類似 BSD 授權與 MIT 授權的 PostgreSQL 授權下發行。

PostgreSQL 這個單字的拼法讓有些人覺得很難讀，特別是那些把 SQL 讀作 "sequel" 的人。PostgreSQL 開發者把它讀作 "post-gress-Q-L"。（Audio sample，5.6k MP3）。它也經常被簡稱為 "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（**T**he **O**versized-**A**ttribute **S**torage **T**echnique，超大屬性儲存技術）用以透明地將超大表屬性（如大 MIME 附件或 XML 訊息）壓縮後儲存至獨立的區域
* 正規表示式

### 資料庫管理及開發工具

* phpPgAdmin 基於 php 語言寫的用於管理 PostgreSQL 資料庫的程式
* PgAdmin 另外一個用於管理 PostgreSQL 資料庫的軟體

### 擴充

* 地理資料物件：PostGIS GPL
* 全文檢索：通過 Tsearch2 或 OpenFTS，將在 8.3 版本中內嵌 Tsearch2。GPL
* 多種非同步主／從複製方案，包括 Slony-I（BSD 授權），Mammoth Replicator
* XML/XSLT 支援 contrib 軟體套件中的 XPath 擴充 GPL

## 知名客戶

## 版本

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（頁面存檔備份，存於網際網路檔案館）