第 1 章 基礎(chǔ)知識(shí)
PostgreSQL 是一款極其強(qiáng)大的數(shù)據(jù)庫,它的很多特性可能是你前所未見
的。它的部分特性在其他知名數(shù)據(jù)庫中也有,但名稱可能不同。在深入
鉆研官方手冊(cè)之前,你需要了解一些核心概念,本章將為你介紹這些概
念,期間也會(huì)涉及其他數(shù)據(jù)庫中的相關(guān)概念和術(shù)語。
本章將首先介紹如何下載和安裝 PostgreSQL,然后會(huì)介紹一些必備的管
理工具和 PostgreSQL 術(shù)語。本書寫作之時(shí),PostgreSQL 10 已發(fā)布,我
們將重點(diǎn)介紹該版本的一些新特性。本章末尾會(huì)提供一些幫助資源,當(dāng)
你需要額外的幫助或者報(bào)告 bug 時(shí)會(huì)用得到。
1.1 為什么應(yīng)該選擇PostgreSQL
PostgreSQL是一款企業(yè)級(jí)關(guān)系型數(shù)據(jù)庫管理系統(tǒng),即使與 Oracle、
Microsoft SQL Server、IBM DB2 等業(yè)界最好的商用數(shù)據(jù)庫相比也毫不
遜色。PostgreSQL 之所以如此特別,是因?yàn)樗粌H僅是一個(gè)數(shù)據(jù)庫,還
是一個(gè)功能強(qiáng)大的應(yīng)用開發(fā)平臺(tái)。
PostgreSQL 的速度很快。大量的評(píng)測數(shù)據(jù)已經(jīng)表明:與其商用以及開源
競爭對(duì)手相比,PostgreSQL 的速度要么遠(yuǎn)遠(yuǎn)勝出,要么旗鼓相當(dāng)。
PostgreSQL 支持用多種編程語言編寫存儲(chǔ)過程和函數(shù)。除了系統(tǒng)自帶的
C、SQL 和 PL/ pgSQL 編程語言外,還可以通過安裝擴(kuò)展包來支持
PL/Perl、PL/Python、PL/V8(又稱為 PL/JAVAScript)、PL/Ruby 以及
PL/R 等。這種支持多語言的能力可以讓開發(fā)人員根據(jù)待解決問題的特
點(diǎn)來選擇最合適的語言。比如可以使用 R 語言來解決統(tǒng)計(jì)和圖形領(lǐng)域的
問題,通過 Python 來調(diào)用 Web 服務(wù),通過使用 SciPy 庫來進(jìn)行科學(xué)計(jì)
算,通過 PL/V8 來進(jìn)行數(shù)據(jù)驗(yàn)證、字符串處理和 JSON 數(shù)據(jù)處理,等
等。PostgreSQL 不但支持種類繁多的開發(fā)語言,使用過程也很簡單:先
找到你需要的函數(shù),看下它是用什么語言編寫的,在 PostgreSQL 中安
裝好支持該語言的擴(kuò)展包,然后把代碼復(fù)制過來就可以執(zhí)行了。真的不
能更簡單。
大多數(shù)數(shù)據(jù)庫會(huì)限制用戶只能使用預(yù)定義的數(shù)據(jù)類型,比如整型、字符
串、文本型、布爾型等。PostgreSQL 在數(shù)據(jù)類型的支持方面有兩個(gè)優(yōu)
勢:不但支持比絕大多數(shù)數(shù)據(jù)庫更豐富的原生數(shù)據(jù)類型,而且還允許用
戶按需自定義數(shù)據(jù)類型。如果用戶需要更復(fù)雜的數(shù)字類型,那么可以定
義包含兩個(gè)浮點(diǎn)類型(float)的復(fù)合類型;如果需要定義一個(gè)三角形,
那么可以先定義一種“坐標(biāo)”類型,然后再定義一種包含三個(gè)坐標(biāo)的“三角形”
類型即可;
如果你對(duì)十二進(jìn)制感興趣,那么可以定義你自己的十二進(jìn)制類型。值得注
意的是,要想自定義類型完全發(fā)揮出其威力,需要有相應(yīng)的運(yùn)算符和函數(shù)
來識(shí)別并配合它。因此,如果你自定義了一種特殊的數(shù)值類型,千萬不要
忘了為它重定義配套的數(shù)學(xué)運(yùn)算符。是的,你沒看錯(cuò),PostgreSQL 允許用
戶重定義基礎(chǔ)運(yùn)算符(+、-、/、*)的實(shí)現(xiàn)邏輯。另外,用戶自定義一種數(shù)
據(jù)類型后,PostgreSQL 會(huì)自動(dòng)定義出一種基于該類型的數(shù)組類型。因此,
如果你定義了一種復(fù)合數(shù)據(jù)類型,那么該復(fù)合數(shù)據(jù)類型的數(shù)組類型自動(dòng)就有
了,你無須做額外的定義工作。
PostgreSQL 會(huì)為每一張用戶表自動(dòng)創(chuàng)建一個(gè)數(shù)據(jù)類型定義。比如我們創(chuàng)
建了一張名為 dogs 的表,包含 breed(品種)、cuteness(可愛程
度)、barkiness(愛叫的程度)等字段,那么 PostgreSQL 會(huì)自動(dòng)在后臺(tái)
創(chuàng)建一個(gè)同名的dogs數(shù)據(jù)類型。這一特性將關(guān)系型數(shù)據(jù)庫領(lǐng)域
的“表”概念與面向?qū)ο箢I(lǐng)域的“對(duì)象”概念緊密地聯(lián)系到了一起,用戶可
以像處理對(duì)象實(shí)例一樣去處理記錄。比如你可以創(chuàng)建一個(gè)函數(shù)來每次處
理一個(gè)或者一批對(duì)象實(shí)例。PostgreSQL 的很多第三方擴(kuò)展包就利用該自
定義數(shù)據(jù)類型能力來優(yōu)化性能,或者通過添加支持某個(gè)領(lǐng)域?qū)S玫奶厥?/p>
SQL 語法來讓業(yè)務(wù)代碼更簡潔和易于維護(hù),或者實(shí)現(xiàn)一些在別的數(shù)據(jù)庫
中完全不可能實(shí)現(xiàn)的功能。
我們建議用戶不要把數(shù)據(jù)庫僅僅當(dāng)成一個(gè)數(shù)據(jù)容器,像 PostgreSQL 這
樣的數(shù)據(jù)庫其實(shí)是一個(gè)成熟而完整的應(yīng)用開發(fā)平臺(tái)。你會(huì)發(fā)現(xiàn):強(qiáng)大的
數(shù)據(jù)庫在手,其他一切都是過眼云煙。一旦你成了 SQL 高手,別人用
其他工具需要幾小時(shí)才能完成的工作,你在數(shù)據(jù)庫里只需要幾秒鐘。不
管是對(duì)比編碼時(shí)間還是對(duì)比實(shí)際數(shù)據(jù)處理時(shí)間,效果都是如此。
近年來,我們看到很多 NoSQL 數(shù)據(jù)庫異軍突起,一時(shí)風(fēng)頭無兩(我們
認(rèn)為這里面有很大的炒作成分)。盡管 PostgreSQL 總體上看是一個(gè)關(guān)系
型數(shù)據(jù)庫,但它其實(shí)也具備強(qiáng)大的處理非關(guān)系型數(shù)據(jù)的能力。比如
ltree 這個(gè)插件可以處理圖數(shù)據(jù),但我們幾乎已經(jīng)想不起它到底是何時(shí)被
加入到 PostgreSQL 中的;又比如 hstore 插件可以實(shí)現(xiàn)鍵值存儲(chǔ);還有
JSON 和 JSONB 類型可以提供類似 MongoDB 的文檔操作能力。從很多
方面來看,PostgreSQL 甚至在“NoSQL”這個(gè)詞出現(xiàn)之前就已經(jīng)提供了那
些所謂的 NoSQL 特性。
如果從 Postgres95 正式改名為 PostgreSQL 開始算起,PostgreSQL 已經(jīng)
誕生二十年了,但事實(shí)上它的歷史可向前一直追溯到
1986年。 PostgreSQL 支持當(dāng)前所有主流的操作系統(tǒng),包括 linux、Unix、
windows 以及 mac。目前每年會(huì)發(fā)布一個(gè)大版本,包含性能提升以及那
些不斷超越關(guān)系型數(shù)據(jù)庫功能極限的新功能。
從 1986 年開始,Stonebraker 教授發(fā)表了一系列論文,引入對(duì)象關(guān)系理念,
探討了新的數(shù)據(jù)庫的結(jié)構(gòu)設(shè)計(jì)和擴(kuò)展設(shè)計(jì)。1988 年,他發(fā)表了 Postgres 的
第一個(gè)原型設(shè)計(jì),
1989 年 6 月發(fā)布了版本
1。因此 1986 年可視為 PostgreSQL 發(fā)展史的元年。——譯者注
最后值得一提的是,PostgreSQL 不但是開源的,而且開源得非常徹底,
它的許可策略非常寬松。現(xiàn)在 PostgreSQL 社區(qū)由一群無私奉獻(xiàn)的的開
發(fā)者和用戶構(gòu)成,他們并不把賺錢視為人生終極目標(biāo)。如果需要新特
性,你可以自行貢獻(xiàn)代碼或者提出訴求。如果你試圖修改 PostgreSQL
代碼以為己所用,也不會(huì)有人起訴你。是成千上萬用戶的參與和貢獻(xiàn)使
得 PostgreSQL 變成了它今日的模樣。
到最后你會(huì)想:我為什么還要使用別家的數(shù)據(jù)庫?PostgreSQL 已經(jīng)提供
了我所需要的一切功能,而且還是免費(fèi)的!你不再需要去閱讀那些商業(yè)
數(shù)據(jù)庫附帶的密密麻麻的授權(quán)條款,來了解在一個(gè)八核虛擬機(jī)上支持 X
個(gè)并發(fā)連接所需要的費(fèi)用是多少,也不需要了解每次升級(jí)后要再為許可
證加多少錢。
1
11.2 不適用PostgreSQL的場景
在為 PostgreSQL 做了這么多“鼓吹”之后,我們也應(yīng)介紹一下它不適用
于哪些場景。
在不安裝任何擴(kuò)展包的情況下,PostgreSQL 需占用 100MB 以上的磁盤
空間,可以看出它的個(gè)頭還是比較大的。因此,在一些存儲(chǔ)空間極為有
限的小型設(shè)備上使用 PostgreSQL 是不合適的,把 PostgreSQL 當(dāng)成簡單
的緩存區(qū)來用也是不合適的,此時(shí)應(yīng)選用一些更輕量級(jí)的數(shù)據(jù)庫。
作為一款企業(yè)級(jí)數(shù)據(jù)庫產(chǎn)品,PostgreSQL 對(duì)于安全是極其重視的。因
此,如果你在開發(fā)一個(gè)把安全管理放到應(yīng)用層去做的輕量級(jí)應(yīng)用,那么
PostgreSQL 完善的安全機(jī)制反倒會(huì)成為負(fù)擔(dān),因?yàn)樗慕巧蜋?quán)限管理
非常復(fù)雜,會(huì)帶來不必要的管理復(fù)雜度和性能損耗。此時(shí)可以考慮選用
SQLite 這樣的單用戶數(shù)據(jù)庫,或者選用 FireBird 這樣既能以客戶端 / 服
務(wù)器模式運(yùn)行也能以嵌入式單用戶模式運(yùn)行的數(shù)據(jù)庫。
通過上述介紹可以看到,一般來說需要將 PostgreSQL 與別的數(shù)據(jù)庫搭
配使用,使它們各展所長。一種常見的組合是把 redis 或者 Memcache
當(dāng)成 PostgreSQL 的查詢緩存來用;另一種組合是用 PostgreSQL 做主數(shù)
據(jù)庫,用 SQLite 存儲(chǔ)離線數(shù)據(jù)來做離線查詢。
令人遺憾的一個(gè)事實(shí)是,很多共享主機(jī)服務(wù)(多個(gè)用戶共享同一個(gè)操作
系統(tǒng)實(shí)例)供應(yīng)商并不支持預(yù)安裝 PostgreSQL,或者只支持安裝一個(gè)很
陳舊的版本。它們更喜歡預(yù)裝較弱的 MySQL。對(duì)于一個(gè) Web 設(shè)計(jì)人員
來說,用什么數(shù)據(jù)庫并不是首要問題,此時(shí) MySQL 可能能夠滿足要
求。但當(dāng)用戶的 SQL 技能不斷提升,不再滿足于寫一寫單表 select 或者
簡單的 join 查詢時(shí),MySQL 的缺點(diǎn)就會(huì)暴露無遺。自本書第一版出版
以來,虛擬化技術(shù)的進(jìn)步使得商業(yè)化的云主機(jī)服務(wù)得到了長足的發(fā)展,因此
擁有自己的獨(dú)立云主機(jī)不再是一件很奢侈的事情。當(dāng)用戶擁有自己
的獨(dú)立云主機(jī)時(shí),就可以自由選擇在上面安裝什么軟件。隨著
PaaS(平臺(tái)即服務(wù))、DBaaS(數(shù)據(jù)庫即服務(wù))等云計(jì)算模式的流行,
PostgreSQL的發(fā)展前景向好。絕大多數(shù)的云服務(wù)廠商都提供
PostgreSQL 服務(wù),其中比較著名的有 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
若干年前,你只能通過手動(dòng)編譯源碼的方式來安裝 PostgreSQL。還好那
種痛苦的時(shí)代已經(jīng)一去不復(fù)返了。當(dāng)然,現(xiàn)在依然可以通過編譯源碼來
安裝,但大多數(shù)用戶會(huì)使用制作好的安裝包來安裝,只需敲擊幾下鍵盤
和鼠標(biāo)就可以了。
如果你是首次安裝 PostgreSQL,那么應(yīng)該選擇適用于你的操作系統(tǒng)平臺(tái)
的最新穩(wěn)定版發(fā)行包。PostgreSQL 官方站點(diǎn)的核心發(fā)布頁面上維護(hù)了一
個(gè)列表,記錄了適用于各操作系統(tǒng)的二進(jìn)制包的下載地址。在附錄
A
中,你會(huì)看到安裝指導(dǎo)和一些定制版本的下載鏈接地址。
1.4 管理工具
PostgreSQL 常用的管理工具有四種:psql、pgAdmin、phpPgAdmin 和
Adminer。PostgreSQL 的核心開發(fā)團(tuán)隊(duì)維護(hù)著前三種,因此它們一般會(huì)
隨著 PostgreSQL 的版本發(fā)布而同步更新。Adminer 并非 PostgreSQL 的
專用管理工具,它支持管理多種類型的關(guān)系型數(shù)據(jù)庫,包括 SQLite、
MySQL、SQL Server 和 Oracle。除了剛剛提到的這四種以外,還有大量
優(yōu)秀的管理工具,開源的和商業(yè)的都有。
1.4.1 psql
psql 是一種用于執(zhí)行查詢的命令行工具,每個(gè) PostgreSQL 發(fā)行版中都
自帶 psql(參見附錄 B.4 節(jié))。它有一些獨(dú)特的功能,比如導(dǎo)入和導(dǎo)出
基于分隔符(逗號(hào)或者制表符等)格式的平面數(shù)據(jù)文件,以及生成簡易
的 html 格式報(bào)表等。psql 是 PostgreSQL 從誕生之初就一直附帶的命
令行工具,它是很多高級(jí)用戶日常操作工具的不二之選,非常適用于只
有控制臺(tái)字符界面而無圖形用戶界面的使用場景。另外,在通過 shell
腳本執(zhí)行數(shù)據(jù)庫操作時(shí),psql 也是必備工具。不過新用戶一般更喜歡使
用圖形界面工具,而且也無法理解為什么“老”一代人會(huì)對(duì)命令行方式那
么執(zhí)著。
1.4.2 pgAdmin
pgAdmin 是一款流行的免費(fèi)的 PostgreSQL 圖形界面管理工具。如果你
的 PostgreSQL 安裝包里沒有附帶此工具,請(qǐng)從其官網(wǎng)單獨(dú)下載安裝。
pgAdmin 可在 PostgreSQL 支持的任意一種操作系統(tǒng)平臺(tái)上運(yùn)行。
即使你的數(shù)據(jù)庫安裝在只有控制臺(tái)字符界面的 Linux 服務(wù)器上,只要你
在本地工作站上安裝了 pgAdmin,也可以用這種強(qiáng)大的圖形化工具對(duì)其進(jìn)行管理。
pgAdmin 近期已經(jīng)發(fā)布了它的第四個(gè)大版本,稱為 pgAdmin4。該版本
對(duì)之前的 pgAdmin3 進(jìn)行了徹底的重寫,使用 Python 實(shí)現(xiàn)了“一套代碼
兩種模式運(yùn)行”的效果,一種模式是作為桌面應(yīng)用運(yùn)行,另一種是在瀏
覽器中運(yùn)行。pgAdmin4 當(dāng)前的版本是 1.5。pgAdmin4 的首個(gè)版本是與
PostgreSQL 9.6 同時(shí)發(fā)布的,并被若干 PostgreSQL 發(fā)行版作為自帶軟件
一起打包發(fā)布。如前所述,pgAdmin4 既可以作為桌面應(yīng)用運(yùn)行,也可
以在瀏覽器中運(yùn)行。
圖 1-1 是 pgAdmin4 的界面示意圖。圖 1-1:pgAdmin4 的樹狀視圖
如果你對(duì) PostgreSQL 還不太熟悉,那么 pgAdmin 毫無疑問是你開始
PostgreSQL 學(xué)習(xí)之旅的最佳入口。只需在主界面上摸索一下,你就可以
對(duì) PostgreSQL 的豐富功能一覽無遺。如果你正打算逃離 Microsoft SQL
Server 陣營,并且習(xí)慣于 SQL Server 的 Management Studio,那么很快
就能適應(yīng) pgAdmin。
相比 pgAdmin3,pgAdmin4 還有一些短板,但它正在快速補(bǔ)齊并在很多
方面都超過了 pgAdmin3。即便如此,如果你是 PgAdmin3 的長期用戶
并且短期內(nèi)無法切換到 pgAdmin4,那么你可以繼續(xù)使用 BigSQL 公司
提供的 pgAdmin3 LTS(長期支持)版,在對(duì) pgAdmin4 進(jìn)行完善測試
后再切換過去。請(qǐng)務(wù)必牢記,pgAdmin4 才是 pgAdmin 未來的主力版
本,pgAdmin3 只會(huì)維持現(xiàn)狀,不會(huì)再有什么發(fā)展。
1.4.3 phpPgAdmin
phpPgAdmin 是一種免費(fèi)的基于 Web 頁面的管理工具,其界面如圖 1-2
所示。它是從流行的 MySQL 管理工具 phpMyAdmin 移植而來的,二者
的差別主要在于 phpPgAdmin 新增了對(duì) PostgreSQL 的 schema、過程式
語言、類型轉(zhuǎn)換器、運(yùn)算符等對(duì)象的管理功能。如果你對(duì) phpMyAdmin
很熟悉,會(huì)發(fā)現(xiàn) phpPgAdmin 的界面風(fēng)格與其完全類似。圖 1-2:phpPgAdmin
1.4.4 Adminer
如果你正在尋找一款除了能夠管理 PostgreSQL,還能管理別的數(shù)據(jù)庫的
整合型工具,那么 Adminer 將是你合適的選擇。Adminer 是一款輕量級(jí)
的開源 PHP 應(yīng)用程序,可以在同一套圖形界面上管理 PostgreSQL、
MySQL、SQLite、SQL Server 以及 Oracle 等多種數(shù)據(jù)庫。
Adminer 有一種獨(dú)特的功能讓我們印象深刻:它能夠以圖形化方式展示
數(shù)據(jù)庫中的對(duì)象,并將外鍵約束關(guān)系以連接線的方式展示出來。另外,
整個(gè) Adminer 程序的本體僅包含一個(gè) PHP 文件,非常簡潔,這可以大
大減少你安裝部署時(shí)的麻煩。
圖 1-3 中,左側(cè)是登錄屏幕的截圖,右側(cè)是表間關(guān)系圖形化后呈現(xiàn)的效
果。很多用戶會(huì)因?yàn)榈卿浧聊簧蠜]有填寫端口號(hào)的地方而感到困惑。如
果 PostgreSQL 使用標(biāo)準(zhǔn)的 5432 偵聽端口,那么登錄時(shí)不填也沒問題;
但如果不是,就需要在服務(wù)器名稱后面加上端口號(hào),注意用冒號(hào)分隔主
機(jī)名和端口號(hào),如圖 1-3 所示。圖 1-3:Adminer
對(duì)于簡單的查詢和修改操作來說,Adminer 的功能是足夠的。但為了支
持多種數(shù)據(jù)庫,Adminer 的功能體系已經(jīng)被裁剪成了各數(shù)據(jù)庫均支持的
最小公共集合,因此你無法實(shí)現(xiàn) PostgreSQL 所特有的一些操作,比如
創(chuàng)建新用戶、授予權(quán)限、查詢當(dāng)前權(quán)限列表等。Adminer 為了與它所支
持的各家數(shù)據(jù)庫在概念上保持兼容和通用而將每個(gè) schema 當(dāng)作一個(gè)
database,這使得以圖形化展示表與表之間外鍵關(guān)系這一功能受到了極
大影響,如果兩個(gè)不同 schema 的表之間存在外鍵關(guān)聯(lián)關(guān)系,那么在
Adminer 的界面上是無法展示出來的。如果你是 DBA,那么建議使用
pgAdmin,當(dāng)然也可以安裝一套 Adminer 以備不時(shí)之需。1.5 PostgreSQL數(shù)據(jù)庫對(duì)象
假設(shè)你現(xiàn)在已經(jīng)安裝好了 PostgreSQL,請(qǐng)啟動(dòng)并連接好 pgAdmin,然后
點(diǎn)開左側(cè)的目錄樹,此時(shí)展現(xiàn)在你面前的是一堆令人眼花繚亂的數(shù)據(jù)庫
對(duì)象,有些你可能很熟悉,有些則可能聞所未聞。PostgreSQL 對(duì)象類型
的數(shù)量超過了絕大多數(shù)關(guān)系型數(shù)據(jù)庫(這還是在未安裝任何擴(kuò)展包的情
況下)。這些對(duì)象中,有許多你可能永遠(yuǎn)都不會(huì)用到,但如果你發(fā)現(xiàn)業(yè)
務(wù)上需要實(shí)現(xiàn)一種新的對(duì)象類型,那么一般來說你要實(shí)現(xiàn)的東西在那一
堆眼花繚亂的對(duì)象中已經(jīng)有前人實(shí)現(xiàn)過了,所以只需要正確選用即可。
本書不會(huì)介紹 PostgreSQL 以標(biāo)準(zhǔn)方式安裝完畢后所提供的所有對(duì)象類
型,因?yàn)?PostgreSQL 引入新特性的速度驚人,任何一本書都不可能全
面覆蓋所有對(duì)象類型。因此我們僅討論你有必要了解的那些對(duì)象類型。
database2
2database 一詞含義寬泛,既可表示廣義的數(shù)據(jù)庫系統(tǒng),又可以表示某些特定數(shù)據(jù)庫系統(tǒng)中的
某一級(jí)數(shù)據(jù)存儲(chǔ)單位,如表述不當(dāng)極易給讀者造成混淆。因此本書中會(huì)區(qū)別使用,表示廣義的
數(shù)據(jù)庫系統(tǒng)時(shí),用中文“數(shù)據(jù)庫”;表示狹義的數(shù)據(jù)存儲(chǔ)單位時(shí),用英文“database”。——譯者
注
每個(gè) PostgreSQL 服務(wù)可以包含多個(gè)獨(dú)立的 database。
schema3
3數(shù)據(jù)庫業(yè)界對(duì)于 schema 有多種譯法:綱要、模式、方案,等等。但各種譯法都不能準(zhǔn)確直觀
地表達(dá)出其原本的含義,即位于一個(gè)獨(dú)立命名空間內(nèi)的一組相關(guān)數(shù)據(jù)庫對(duì)象的集合,因此前述
譯法從來沒有一種成為主流。一般業(yè)界人員都直接使用英文 schema。考慮到這個(gè)情況,為防
止初級(jí)用戶理解困難,我們也按照業(yè)界習(xí)慣直接使用英文原名。——譯者注
ANSI SQL 標(biāo)準(zhǔn)中對(duì) schema 有著明確的定義,database 的下一層邏
輯結(jié)構(gòu)就是 schema。如果把 database 比作一個(gè)國家,那么 schema 就是一些獨(dú)立的州
(或者是省、府、轄區(qū)等,具體取決于各國的實(shí)際情況)。大多數(shù)對(duì)象
是隸屬于某個(gè) schema 的,然后 schema 又隸屬于某個(gè) database。在創(chuàng)建
一個(gè)新的 database 時(shí),PostgreSQL 會(huì)自動(dòng)為其創(chuàng)建一個(gè)名為 public 的
schema。如果未設(shè)置
search_path
變量(后續(xù)會(huì)介紹該變量的含
義),那么 PostgreSQL 會(huì)將你創(chuàng)建的所有對(duì)象默認(rèn)放入 public schema
中。如果表的數(shù)量較少,這是沒問題的,但如果你有幾千張表,那么我
們還是建議你將它們分門別類放入不同的 schema 中。
表
任何一個(gè)數(shù)據(jù)庫中,表都是最核心的對(duì)象類型。在
PostgreSQL
中,表首先屬于某個(gè) schema,而 schema 又屬于某個(gè) database,這樣就
構(gòu)成了一種三級(jí)存儲(chǔ)結(jié)構(gòu)。
PostgreSQL 的表支持兩種很強(qiáng)大的功能。第一種是表繼承,即一張
表可以有父表和子表。這種層次化的結(jié)構(gòu)可以極大地簡化數(shù)據(jù)庫設(shè)計(jì),
還可以為你省掉大量的重復(fù)查詢代碼。第二種是創(chuàng)建一張表的同時(shí),系
統(tǒng)會(huì)自動(dòng)為此表創(chuàng)建一種對(duì)應(yīng)的自定義數(shù)據(jù)類型。
視圖
大多數(shù)關(guān)系型數(shù)據(jù)庫都支持視圖。視圖是基于表的一種抽象,通過
它可以實(shí)現(xiàn)一次性查詢多張表,也可以實(shí)現(xiàn)通過復(fù)雜運(yùn)算來構(gòu)造出虛擬
字段。視圖一般是只讀的,但 PostgreSQL 支持對(duì)視圖數(shù)據(jù)進(jìn)行修改,
前提是該視圖基于單張實(shí)體表構(gòu)建。如果需要修改基于多張表關(guān)聯(lián)而來
的視圖,可以針對(duì)視圖編寫觸發(fā)器。9.3
版還引入了對(duì)物化視圖的支
持,該機(jī)制通過對(duì)視圖數(shù)據(jù)進(jìn)行緩存來實(shí)現(xiàn)對(duì)常用查詢的加速,缺點(diǎn)是
查到的數(shù)據(jù)可能不是最新的。更多細(xì)節(jié)請(qǐng)參見 7.1.3 節(jié)。擴(kuò)展包
開發(fā)人員可以通過該機(jī)制將一組相關(guān)的函數(shù)、數(shù)據(jù)類型、數(shù)據(jù)類型
轉(zhuǎn)換器、用戶自定義索引、表以及屬性變量等對(duì)象打包成一個(gè)功能擴(kuò)展
包,該擴(kuò)展包可以整體安裝和刪除。擴(kuò)展包在概念上與
Oracle
的
package 類似,從 PostgreSQL 9.1 版本之后一般推薦使用該機(jī)制來為數(shù)
據(jù)庫提供功能擴(kuò)展。擴(kuò)展包的具體安裝步驟,請(qǐng)參考開發(fā)手冊(cè)。一般來
說,需要先將擴(kuò)展包的二進(jìn)制安裝包和腳本復(fù)制到 PostgreSQL 安裝目
錄下,然后運(yùn)行一系列腳本,再在需要其功能的 database 中單獨(dú)安裝該
擴(kuò)展包。注意:僅需在需要該擴(kuò)展包功能的 database 中安裝,不必為當(dāng)
前數(shù)據(jù)庫系統(tǒng)中的每個(gè) database 都安裝。比如需要對(duì)某個(gè) database 中的
數(shù)據(jù)進(jìn)行高級(jí)文本搜索,那么單獨(dú)在該
database
中安裝
fuzzystrmatch 擴(kuò)展包即可。
安裝擴(kuò)展包時(shí)可以指定該包中所含有的成員對(duì)象安裝到哪個(gè)
schema,若不指定則默認(rèn)會(huì)安裝到 public schema 中。我們不建議采用
默認(rèn)設(shè)置,因?yàn)檫@會(huì)導(dǎo)致 public schema 變得龐大復(fù)雜且難以管理,尤
其是如果你將自己的數(shù)據(jù)庫對(duì)象也都存入 public schema 中,那么情況
會(huì)變得更糟糕。我們建議你創(chuàng)建一個(gè)獨(dú)立的 schema 用于存放所有擴(kuò)展
包的對(duì)象,甚至為規(guī)模較大的擴(kuò)展包單獨(dú)創(chuàng)建一個(gè) schema。為避免出
現(xiàn)找不到新增擴(kuò)展包對(duì)象的問題,請(qǐng)將這些新增的 schema 名稱加入
search_path 變量中,這樣就可以直接使用擴(kuò)展包的功能而無須關(guān)注
它到底安裝到了哪個(gè) schema 中。也有一些擴(kuò)展包明確要求必須安裝到
某個(gè) schema 下(特別是過程式語言擴(kuò)展包),這種情況下你就不能自
行指定了。有很多語言擴(kuò)展包,比如
plv8,就要求必須安裝到
pg_catalog schema 中。
多個(gè)擴(kuò)展包之間可能存在依賴關(guān)系。在 PostgreSQL 9.6 之前,你需
要了解這個(gè)依賴關(guān)系并把被依賴包先裝好,但從 9.6 版開始,只需在安裝時(shí)加上 cascade 關(guān)鍵字,PostgreSQL 就會(huì)自動(dòng)安裝當(dāng)前擴(kuò)展包所依
賴的擴(kuò)展包。例如:
CREATE EXTENSION postgis_tiger_geocoder CASCADE;
這條命令會(huì)先尋找并安裝被依賴的 postgis 和 fuzzystrmatch 這
兩個(gè)擴(kuò)展包,當(dāng)然,如果原本就有了,就不需要了。
函數(shù)
用戶可以編寫自定義函數(shù)來對(duì)數(shù)據(jù)進(jìn)行新增、修改、刪除和復(fù)雜計(jì)
算等操作,可以使用 PostgreSQL 所支持的各種過程式語言來編碼。
PostgreSQL
裝好以后自身就包含了數(shù)以千計(jì)的系統(tǒng)函數(shù),都在默認(rèn)的
postgres
庫中。函數(shù)支持返回以下數(shù)據(jù)類型:標(biāo)量值(也就是單個(gè)
值)、數(shù)組、單條記錄以及記錄集。其他數(shù)據(jù)庫將對(duì)數(shù)據(jù)進(jìn)行增刪改操
作的函數(shù)稱為“存儲(chǔ)過程”,把不進(jìn)行增刪改的函數(shù)叫作“函數(shù)”,但
PostgreSQL 中并不區(qū)分,統(tǒng)一把二者稱為“函數(shù)”。
內(nèi)置編程語言
函數(shù)是以過程式語言編寫的。PostgreSQL 默認(rèn)支持三種內(nèi)置編程語
言:SQL、PL/pgSQL 以及 C 語言。可以通過 CREATE EXTENSION 或者
CREATE PRODCEDURAL LANGUAGE 命令來添加其他語言。目前較常用的
語言是 PL/Python、PL/V8(即 JavaScript)以及 PL/R。我們將在第 8 章
中展示大量的相關(guān)示例。
運(yùn)算符
運(yùn)算符本質(zhì)上是以簡單符號(hào)形式呈現(xiàn)的函數(shù)別名,例如 =、&& 等。
PostgreSQL 支持自定義運(yùn)算符。如果用戶定義了自己的數(shù)據(jù)類型,那么
一般來說需要再自定義一些運(yùn)算符來與之配合工作。比如你定義了一個(gè)復(fù)數(shù)類型,那么你很有可能需要自定義 +、-、*、/ 這幾個(gè)運(yùn)算符來對(duì)
復(fù)數(shù)進(jìn)行運(yùn)算。
外部表和外部數(shù)據(jù)封裝器
外部表是一些虛擬表,通過它們可以直接在本地?cái)?shù)據(jù)庫中訪問來自
外部數(shù)據(jù)源的數(shù)據(jù)。只要數(shù)據(jù)映射關(guān)系配置正確,外部表的用法就與普
通表沒有任何區(qū)別。外部表支持映射到以下類型的數(shù)據(jù)源:CSV 文件、
另一個(gè)服務(wù)器上的 PostgreSQL 表、SQL Server 或 Oracle 這些異構(gòu)數(shù)據(jù)
庫中的表、Redis 這樣的 NoSQL 數(shù)據(jù)庫,甚至像 Twitter 或 Salesforce
這樣的 Web 服務(wù)。
外部表映射關(guān)系的建立是通過配置外部數(shù)據(jù)封裝器(foreign
data
wrApper,F(xiàn)DW)實(shí)現(xiàn)的。FDW 是 PostgreSQL 和外部數(shù)據(jù)源之間的一
架“魔法橋”,可實(shí)現(xiàn)兩邊數(shù)據(jù)的互聯(lián)互通。其內(nèi)部實(shí)現(xiàn)機(jī)制遵循
SQL
標(biāo)準(zhǔn)中的 MED(Management of External Data)規(guī)范,更多細(xì)節(jié)請(qǐng)參考
維基百科上關(guān)于 MED 的描述。
許多無私的開發(fā)者已經(jīng)為當(dāng)下大部分流行的數(shù)據(jù)源開發(fā)了 FDW 并
已免費(fèi)共享出來。你也可以通過創(chuàng)建自己的 FDW 來練習(xí)。(我們建議
你一旦成功了也公布出來,這樣整個(gè)社區(qū)都可以分享你的勞動(dòng)成果。)
FDW 是通過擴(kuò)展包機(jī)制實(shí)現(xiàn)的,安裝好以后在 pgAdmin 界面上名為
Foreign Data Wrapper 的目錄節(jié)點(diǎn)下能看到它。
觸發(fā)器和觸發(fā)器函數(shù)
絕大多數(shù)企業(yè)級(jí)數(shù)據(jù)庫都支持觸發(fā)器機(jī)制,該機(jī)制可以偵測到數(shù)據(jù)
修改事件的發(fā)生。在 PostgreSQL 中,當(dāng)一個(gè)觸發(fā)器被觸發(fā)后,系統(tǒng)會(huì)
自動(dòng)調(diào)用用戶定義好的觸發(fā)器函數(shù)。觸發(fā)器的觸發(fā)時(shí)機(jī)是可設(shè)置的,可
以是語句級(jí)觸發(fā)或者記錄級(jí)觸發(fā),也可以是修改前觸發(fā)或修改后觸發(fā)。在 pgAdmin 中,如果希望了解哪些表上掛載了觸發(fā)器,只需在對(duì)
象樹上層層點(diǎn)擊,一直打開到表這一級(jí),然后可以看到下面有個(gè) trigger
子欄目,里面就是該表的所有觸發(fā)器。
定義觸發(fā)器時(shí)需要定義對(duì)應(yīng)的觸發(fā)器函數(shù),這類函數(shù)與前面介紹過
的普通函數(shù)有所不同,主要差異在于觸發(fā)器函數(shù)可以通過系統(tǒng)內(nèi)置變量
來同時(shí)訪問到修改前和修改后的數(shù)據(jù),這樣就可以實(shí)現(xiàn)對(duì)于非法的數(shù)據(jù)
修改行為的識(shí)別和攔截。因此觸發(fā)器函數(shù)一般會(huì)用于編寫復(fù)雜校驗(yàn)邏
輯,這類復(fù)雜邏輯通過 check 約束是無法實(shí)現(xiàn)的。
PostgreSQL 的觸發(fā)器技術(shù)正在快速的演進(jìn)之中。9.0 版引入了對(duì)
WITH 子句的支持,通過它可以實(shí)現(xiàn)帶條件的記錄級(jí)觸發(fā),即只有當(dāng)某
條記錄符合指定的 WHEN 條件時(shí),觸發(fā)器才會(huì)被調(diào)用。9.0 版還引入了
UPDATE OF 子句,通過它可以實(shí)現(xiàn)精確到字段級(jí)的觸發(fā)條件設(shè)置。僅當(dāng)
指定的字段內(nèi)容被更改時(shí)才會(huì)激活觸發(fā)器。9.1 版支持了針對(duì)視圖的觸
發(fā)器。9.3 版支持了針對(duì) DDL 的觸發(fā)器。目前支持觸發(fā)器的 DDL 命令
列表請(qǐng)參見官方手冊(cè)中“觸發(fā)器觸發(fā)時(shí)機(jī)一覽表”。pgAdmin
中會(huì)把
DDL 觸發(fā)器列在 event trigger 這一欄下。最后值得一提的是,從 9.4 版
開始,針對(duì)外部表的觸發(fā)器也獲得了支持。
catalog
catalog 的譯法與 schema 存在相同的問題,翻譯為“目錄”后并不能讓讀者準(zhǔn)確地理解其原意,
反而容易造成混淆,因此還是沿用英文原名。——譯者注
catalog 是系統(tǒng)級(jí)的 schema,用于存儲(chǔ)系統(tǒng)函數(shù)和系統(tǒng)元數(shù)據(jù)。每
個(gè)
database
創(chuàng)建好以后默認(rèn)都會(huì)含有兩個(gè)
catalog:一個(gè)名為
pg_catalog,用于存儲(chǔ) PostgreSQL 系統(tǒng)自帶的函數(shù)、表、系統(tǒng)視圖、
數(shù)據(jù)類型轉(zhuǎn)換器以及數(shù)據(jù)類型定義等元數(shù)據(jù);另一個(gè)是
information_schema,用于存儲(chǔ) ANSI 標(biāo)準(zhǔn)中所要求提供的元數(shù)據(jù)查
4
4詢視圖,這些視圖遵從 ANSI SQL 標(biāo)準(zhǔn)的要求,以指定的格式向外界提
供 PostgreSQL 元數(shù)據(jù)信息。
一直以來,PostgreSQL 數(shù)據(jù)庫的發(fā)展都嚴(yán)格地遵循著其“自由與開
放”的核心理念。如果你足夠了解這款數(shù)據(jù)庫,會(huì)發(fā)現(xiàn)它幾乎是一種可
以“自我生長”的數(shù)據(jù)庫。比如,它所有的核心設(shè)置都保存在系統(tǒng)表中,
用戶可以不受限地查看和修改這些數(shù)據(jù),這為 PostgreSQL 提供了遠(yuǎn)超
任何一種商業(yè)數(shù)據(jù)庫的巨大靈活性(不過從另一個(gè)角度看,將這種靈活
性稱為“可破壞性”也未嘗不可)。只要仔細(xì)地研究一下 pg_catalog,
你就可以了解到 PostgreSQL 這樣一個(gè)龐大的系統(tǒng)是如何基于各種部件
構(gòu)建起來的。如果你有超級(jí)用戶權(quán)限,那么可以直接修改 pg_catalog
的內(nèi)容(當(dāng)然,如果改得不對(duì),那你的行為就跟搞破壞沒什么兩樣
了)。
Information_schema catalog 在 MySQL 和 SQL Server 中也有。
PostgreSQL 的 Information_schema 中最常用的視圖一般有以下幾
個(gè):columns 視圖,列出了數(shù)據(jù)庫中的所有字段; tables 視圖,列出
了數(shù)據(jù)庫中的所有表(包括視圖);views 視圖,列出了所有視圖以及
用于創(chuàng)建該視圖的原始 SQL。
類型
類型是數(shù)據(jù)類型的簡稱。每種數(shù)據(jù)庫產(chǎn)品和每種編程語言都會(huì)支持
一系列的數(shù)據(jù)類型,比如整型、字符型、數(shù)組、二進(jìn)制大對(duì)象(blob)
等。除前述常見類型外,PostgreSQL 還支持復(fù)合數(shù)據(jù)類型,這種類型可
以是多種數(shù)據(jù)類型的一個(gè)組合,比如復(fù)數(shù)、極坐標(biāo)、向量、張量等都是
復(fù)合數(shù)據(jù)類型。
PostgreSQL 會(huì)自動(dòng)為用戶自己創(chuàng)建的表定義一個(gè)同名的復(fù)合數(shù)據(jù)類
型。這樣就可以把表記錄當(dāng)作對(duì)象實(shí)例來處理。當(dāng)用戶需要在函數(shù)中遍歷表記錄時(shí),該特性特別注意:在 pgAdmin 的界面上你看不到
這些在創(chuàng)建表時(shí)自動(dòng)生成的自定義類型,但請(qǐng)放心,這并不代表它們不
存在。
全文檢索
全文檢索(full text search,F(xiàn)TS)是一種基于自然語言的搜索機(jī)
制。這種搜索機(jī)制有一些“智能”成分。與正則表達(dá)式搜索不同,全文檢
索能夠基于語義來進(jìn)行匹配查找,而不僅僅是純粹的語法匹配。例如,
用戶需要在一段長文本中搜索 running 這個(gè)詞,那么命中的結(jié)果可能包
含 run、running、jog、sprint、dash 等詞。全文檢索功能依賴于 FTS 配
置庫、FTS 詞典、FTS 解析器這三個(gè)部件。有了它們,PostgreSQL 原生
的 FTS 功能即可正常使用。一般場景下的全文檢索靠這三個(gè)原生部件
已經(jīng)足夠,但在涉及藥理學(xué)、有組織犯罪學(xué)等專業(yè)場景下,搜索目標(biāo)文
本中會(huì)包括該領(lǐng)域?qū)S性~匯和特殊語法規(guī)則,此時(shí)需要用專門的
FTS
部件來替換原生 FTS 部件。我們會(huì)在 5.8 節(jié)探討 FTS 功能。
數(shù)據(jù)類型轉(zhuǎn)換器
數(shù)據(jù)類型轉(zhuǎn)換器可以將一種數(shù)據(jù)類型轉(zhuǎn)換為另一種,其底層通過調(diào)
用轉(zhuǎn)換函數(shù)來實(shí)現(xiàn)真正的轉(zhuǎn)換邏輯。PostgreSQL 支持用戶自定義轉(zhuǎn)換器
或者重載、加強(qiáng)默認(rèn)的轉(zhuǎn)換器。例如,如果你需要把郵政編碼(美國的
郵政編碼是一個(gè) 5 位的整數(shù))從 integer 轉(zhuǎn)換為 character,那么可
以自定義一個(gè)支持“數(shù)字不足 5 位則前面自動(dòng)補(bǔ) 0”規(guī)則的轉(zhuǎn)換器。
轉(zhuǎn)換器可以被隱式調(diào)用也可以被顯式調(diào)用。隱式轉(zhuǎn)換是系統(tǒng)自動(dòng)執(zhí)
行的,一般來說,將一種特定數(shù)據(jù)類型轉(zhuǎn)為更通用的數(shù)據(jù)類型(比如數(shù)
字轉(zhuǎn)換為字符串)時(shí)就會(huì)發(fā)生隱式類型轉(zhuǎn)換。如果進(jìn)行隱式轉(zhuǎn)換時(shí)系統(tǒng)
找不到合適的轉(zhuǎn)換器,你就必須顯式執(zhí)行轉(zhuǎn)換動(dòng)作。序列號(hào)生成器
序列號(hào)生成器用于實(shí)現(xiàn) serial 數(shù)據(jù)類型值的自動(dòng)遞增分配。在創(chuàng)
建 serial 字段時(shí),PostgreSQL 會(huì)自動(dòng)為其創(chuàng)建一個(gè)相應(yīng)的序列號(hào)生成
器,但用戶也可以很方便地更改其初始值、步長和下一個(gè)值。因?yàn)樾蛄?/p>
號(hào)生成器是獨(dú)立對(duì)象,所以多個(gè)表可以共享同一個(gè)序列號(hào)生成器。基于
該機(jī)制,用戶可以實(shí)現(xiàn)跨越多個(gè)表的唯一鍵。SQL Server 和 Oracle 也都
支持序列號(hào)生成器,但必須手動(dòng)創(chuàng)建。
規(guī)則
規(guī)則的功能是在一個(gè) SQL 執(zhí)行前對(duì)其進(jìn)行改寫。本書中不會(huì)討論
有關(guān)規(guī)則的內(nèi)容,因?yàn)檫@一技術(shù)已經(jīng)過時(shí),通過觸發(fā)器能實(shí)現(xiàn)相同的功
能。
PostgreSQL 允許用戶對(duì)前述每一種對(duì)象進(jìn)行參數(shù)配置。這些參數(shù)可以在
服務(wù)級(jí)、庫級(jí)、函數(shù)級(jí)等不同層級(jí)生效。你將來很可能會(huì)看到一個(gè)很炫
的詞叫 GUC,意思是“大一統(tǒng)配置”(grand unified configuration),它
實(shí)際上指的就是 PostgreSQL 中的那些配置參數(shù)。1.6 最新版本的PostgreSQL中引入的新特性
PostgreSQL 在每年的 9 月份會(huì)發(fā)布一個(gè)大版本。每個(gè)新版本都會(huì)帶來穩(wěn)
定性、安全性、性能等方面的提升,以及一些前沿的新特性。而且版本
升級(jí)過程也變得越來越簡單。那么顯而易見,請(qǐng)盡量把你的數(shù)據(jù)庫及時(shí)
升級(jí)到最新的穩(wěn)定版。關(guān)于每個(gè)版本引入的關(guān)鍵特性列表,請(qǐng)參見官方
提供的“PostgreSQL 各版本功能特性一覽表”。
1.6.1 為什么要升級(jí)
如果你正在使用 PostgreSQL 9.1 或者更早的版本,請(qǐng)立即升級(jí)!因?yàn)?/p>
9.1 版在 2016 年 9 月已進(jìn)入生命周期終結(jié)(end of life,EOL)狀態(tài)。請(qǐng)
參考 PostgreSQL 官方的發(fā)行版支持策略以獲取更多關(guān)于 PostgreSQL
EOL 政策的細(xì)節(jié)。請(qǐng)務(wù)必不要使用已過了 EOL 期限的版本,因?yàn)殚_發(fā)
組不會(huì)再為其提供新的安全更新和功能補(bǔ)丁。一旦這種老版本出了問
題,你只能花錢去請(qǐng) PostgreSQL 專家級(jí)顧問來解決故障或?qū)ふ遗R時(shí)解
決方案,這種服務(wù)一般都是很昂貴的,而且你不一定能找得到這種專
家。
不管當(dāng)前使用的是哪個(gè)大版本,你都應(yīng)該盡快跟進(jìn)小版本號(hào)的更新。比
如從 9.1.17 升級(jí)到 9.1.21,只需要替換二進(jìn)制文件并重啟一下即可。小
版本僅修改 bug 而不會(huì)涉及功能變化,因此這種升級(jí)是很安全的,也會(huì)
為你降低出問題的概率。
1.6.2 PostgreSQL 10中引入的新特性
PostgreSQL 10 是目前最新的穩(wěn)定版,于 2017 年 10 月發(fā)布。從
PostgreSQL 10 開始,PostgreSQL 會(huì)以一種新的方式升級(jí)其版本號(hào)。在
之前的版本中,發(fā)布大版本時(shí)變化的是第二位小版本號(hào),比如從PostgreSQL 9.5 到 PostgreSQL 9.6,即使增加了一些比較大的新功能,
也只有小版本號(hào)發(fā)生變化。但從 PostgreSQL 10 開始,每個(gè)變化較大的
版本都會(huì)在主版本號(hào)上加一。因此 PostgreSQL 10 的下一個(gè)大版本是
PostgreSQL 11。這樣就與 SQLite、SQL Server、Oracle 等數(shù)據(jù)庫的版本
號(hào)策略保持了一致。
以下是 PostgreSQL 10 中引入的關(guān)鍵新特性。
提升了查詢的并行度
對(duì)于并行查詢啟用了新的優(yōu)化策略,包括并行位圖堆掃描、并行索
引掃描等。這些增強(qiáng)將使得更多查詢語句能被并行執(zhí)行。請(qǐng)參考 9.4 節(jié)
以了解更多信息。
邏輯復(fù)制
此前版本的 PostgreSQL 中已經(jīng)支持流復(fù)制特性。通過流復(fù)制可以
實(shí)現(xiàn)整個(gè) PostgreSQL 服務(wù)實(shí)例的復(fù)制,但該機(jī)制有一些固有的缺點(diǎn):
從節(jié)點(diǎn)是只讀的,只能用于數(shù)據(jù)查詢,不能對(duì)其數(shù)據(jù)進(jìn)行修改;從節(jié)點(diǎn)
上也不能創(chuàng)建自己獨(dú)有的表。邏輯復(fù)制解決了這兩個(gè)問題。通過邏輯復(fù)
制可以實(shí)現(xiàn)僅復(fù)制單張表或者單個(gè) database(不用復(fù)制整個(gè)服務(wù)實(shí)例的
所有數(shù)據(jù))。既然不需要復(fù)制整個(gè)數(shù)據(jù)庫服務(wù),那么自然從庫上就可以
有自己的表和數(shù)據(jù),這部分?jǐn)?shù)據(jù)是不包含在復(fù)制體系中的,因此主從庫
上允許不一樣。
針對(duì) JSON 和 JSONB 類型的全文檢索
此前的版本中,to_tsvector 函數(shù)僅能為文本類型的字段生成全
文檢索向量。現(xiàn)在它已支持處理 JSON 和 JSONB 類型,處理過程中會(huì)
忽略其中 key 的部分,而僅包含 value 的部分。同時(shí) ts_headline 函數(shù)
也專為 JSON 和 JSONB 類型做了適配,它可以對(duì) JSON 內(nèi)容中的關(guān)鍵字進(jìn)行加亮標(biāo)記。詳情請(qǐng)參考 5.8.7 節(jié)。
支持 ANSI 標(biāo)準(zhǔn)中的 XMLTABLE 特性
XMLTABLE 特性可以將 XML 文本內(nèi)容以一種更為簡單的方式映射
為普通二維表記錄。該特性在 Oracle 和 IBM DB2 中已支持。詳情請(qǐng)參
見示例 5-41。
FDW 聚合下推
FDW API 可以將 COUNT(*) 或者 SUM(*) 這種聚合操作推送到遠(yuǎn)端
節(jié)點(diǎn)執(zhí)行。postgres_fdw
插件從該特性中受益最大。此前的版本
中,postgres_fdw 插件在執(zhí)行聚合操作時(shí),需要把所有相關(guān)數(shù)據(jù)從遠(yuǎn)
端 PostgreSQL 取到本地然后再進(jìn)行聚合運(yùn)算,這極大地影響了整體運(yùn)
算效率。
聲明式表分區(qū)
此前的版本中,實(shí)現(xiàn)分區(qū)表功能需要借助表繼承機(jī)制。表繼承機(jī)制
的問題在于,用戶需要自行編寫觸發(fā)器來實(shí)現(xiàn)把數(shù)據(jù)分流到子表中的過
程。PostgreSQL 10 引入了 PARTITION BY 語法,利用該語法,用戶只
需在創(chuàng)建表時(shí)附加 PARTITION BY 子句就可以自動(dòng)實(shí)現(xiàn)表分區(qū)。此后向
父表插入數(shù)據(jù)時(shí),數(shù)據(jù)會(huì)被分流到子表中,這一切都是自動(dòng)的,無須用
戶預(yù)先創(chuàng)建觸發(fā)器。請(qǐng)參考 6.1.3 節(jié)以了解詳情。
查詢性能優(yōu)化
該版本中對(duì)查詢性能實(shí)現(xiàn)了多方面的優(yōu)化。
支持創(chuàng)建多字段統(tǒng)計(jì)信息CREATE STATISTICS 命令支持針對(duì)多個(gè)字段建立統(tǒng)計(jì)信息。具體
請(qǐng)參見示例 9-18。
支持 IDENTITY 數(shù)據(jù)類型
新增支持 IDENTITY 自增字段類型,創(chuàng)建表和修改表結(jié)構(gòu)時(shí)都可以
使用。增加該類型是為了在設(shè)計(jì)表的自增字段時(shí)更加符合業(yè)界通行做
法。具體請(qǐng)參見示例 6-2。
1.6.3 PostgreSQL 9.6中引入的新特性
PostgreSQL 9.6 發(fā)布于 2016 年 9 月,是 9.x 系列中的最新版本。
支持并行查詢
9.6 版之前,PostgreSQL 并不能充分地利用系統(tǒng)中的多核能力。9.6
版中,PostgreSQL 引擎能夠?qū)⒁恍┨囟愋偷牟樵冋Z句放到多個(gè)處理器
核心上并行執(zhí)行。支持并行執(zhí)行的操作有:順序掃描、部分 join 以及部
分聚合操作。然而,增刪改這些修改數(shù)據(jù)的操作無法實(shí)現(xiàn)并行。支持并
行化的工作還在進(jìn)行中,最終目標(biāo)是所有的語句都能利用到多核并行執(zhí)
行。詳情參見 9.4 節(jié)。
支持關(guān)聯(lián)詞組全文檢索
全文檢索支持關(guān)聯(lián)詞組搜索,可以使用 <-> 運(yùn)算符來表示兩個(gè)關(guān)聯(lián)
詞之間的距離。即使關(guān)聯(lián)詞沒有連在一起出現(xiàn),只要二者出現(xiàn)的位置不
超出前述距離,也認(rèn)為該關(guān)聯(lián)詞組搜索命中。在 9.6 之前的版本中,只
能搜索一些單個(gè)的詞,但該功能使得用戶可以搜索一組有前后順序的詞
組。詳情請(qǐng)參見 5.8 節(jié)。
psql 工具支持 gexec 參數(shù)該參數(shù)的功能是讀取并執(zhí)行一個(gè)根據(jù)查詢語句動(dòng)態(tài)生成的 SQL。詳
情請(qǐng)參見 3.4.5 節(jié)。
postgres_fdw 增強(qiáng)
對(duì)于簡單的更新、插入和刪除來說,速度有很大提升。請(qǐng)參考博
文“Directly Modify Foreign Tables”以了解詳情。
FDW 關(guān)聯(lián)操作下推
包括 postgres_fdw 在內(nèi)的部分 FDW 已支持該特性。當(dāng)需要對(duì)多
張外表做關(guān)聯(lián)查詢時(shí),之前的做法是把每張外表的數(shù)據(jù)取回本地然后做
關(guān)聯(lián)計(jì)算,支持了該特性的 FDW 的優(yōu)化處理方式是:如果需要關(guān)聯(lián)的
兩張外表都來自于同一臺(tái)外部服務(wù)器,那么就把 join 操作下推到這個(gè)外
部服務(wù)器上去執(zhí)行,然后僅把關(guān)聯(lián)結(jié)果拿回來。這樣可以極大地減少經(jīng)
網(wǎng)絡(luò)傳輸?shù)挠涗洈?shù)。當(dāng)關(guān)聯(lián)操作可以過濾掉大量數(shù)據(jù)時(shí),這個(gè)特性帶來
的性能提升是巨大的。
1.6.4 PostgreSQL 9.5中引入的新特性
PostgreSQL 9.5 發(fā)布于 2016 年 1 月,其主要的新特性如下。
外部表架構(gòu)的改進(jìn)
支持了新的 IMPORT FOREIGN SCHEMA 命令,通過該命令可以從外
部服務(wù)器中加載表結(jié)構(gòu)信息從而實(shí)現(xiàn)批量創(chuàng)建外表。支持外表繼承:本
地表可以繼承自外表,外表也可以繼承自本地表,外表也可以繼承自另
一張外表。支持在外表上創(chuàng)建約束。詳情請(qǐng)參見 10.3 節(jié)和 10.3.3 節(jié)。
支持無日志表直接升級(jí)為日志表由于無日志表不寫日志,往其中導(dǎo)入數(shù)據(jù)時(shí)會(huì)很快,但缺點(diǎn)是數(shù)據(jù)
庫崩潰時(shí)會(huì)完全丟失數(shù)據(jù)。在此前的版本中,當(dāng)數(shù)據(jù)完全導(dǎo)入無日志表
后,要想把無日志表改為日志表需要?jiǎng)?chuàng)建一張新表,然后再把無日志表
的數(shù)據(jù)寫入新表。9.5 版提供了一個(gè)新的語法:ALTER TABLE ... SET
UNLOGGED,可以直接把無日志表修改為日志表,這樣就省去了重新建
表并搬遷數(shù)據(jù)的過程。
array_agg 函數(shù)支持?jǐn)?shù)組入?yún)?/p>
array_agg 函數(shù)可以將某字段的多條記錄聚合為一個(gè)數(shù)組。在 9.5
版之前,入?yún)⒆侄晤愋筒荒苁且粋€(gè)數(shù)組,但 9.5 版之后支持輸入數(shù)組入
參,這樣就可以構(gòu)造出多維數(shù)組。詳情請(qǐng)參見示例 5-17。
支持 BRIN 索引類型
BRIN(block range index)是一種新型的索引,相比 B-樹和 GIN 索
引有著更小的內(nèi)存占用。有些情況下 BRIN 索引會(huì)比前述兩種索引速度
更快。詳情請(qǐng)參見 6.3 節(jié)。
支持 GROUPING SETS、ROLLUP 和 CUBE 聚合語法
該特性用于聚合查詢語句中,可以實(shí)現(xiàn)一次性獲取多維度匯聚結(jié)
果。具體例子請(qǐng)參見 7.7 節(jié)。
僅索引掃描
如果要查詢的字段在索引中已經(jīng)全部包含,則僅掃描索引即可獲得
查詢結(jié)果,而不用訪問表數(shù)據(jù),這種查詢模式稱為“僅索引掃描”。當(dāng)前
只有 GiST 索引支持此特性。
支持“無則插入有則更新”處理(即 UPSERT 能力)9.5
版之前,如果插入或者更新操作違反了主鍵約束或者其他約
束,那么該操作會(huì)失敗。9.5 版提供了一種機(jī)制,允許用戶捕獲該異常
并自定義替代操作或者跳過引發(fā)問題的記錄。詳情請(qǐng)參見 7.2.11 節(jié)。
支持跳過無法寫鎖定的記錄
如果用戶希望鎖定一些記錄以用于后續(xù)更新,那么可以使用
SELECT ... FOR UPDATE 來鎖定這些記錄。在 9.5 版之前,如果試圖
鎖定的部分或者全部記錄已被其他用戶鎖定,那么當(dāng)前用戶的鎖定操作
就會(huì)報(bào)錯(cuò)。9.5 版中提供了一個(gè) SKIP LOCKED 子句語法,可以跳過那些
已經(jīng)被別人鎖定的記錄,這樣就不會(huì)報(bào)錯(cuò)。
行級(jí)安全控制
支持對(duì)用戶設(shè)置記錄級(jí)的讀寫權(quán)限,即同一張表中,部分記錄只允
許某個(gè)用戶讀寫,另外一部分記錄只允許另外一個(gè)用戶讀寫。在多租戶
場景下,顯然該功能是特別有用的;對(duì)于需要進(jìn)行訪問權(quán)限隔離而又無
法通過分表實(shí)現(xiàn)的場景,該功能也特別有價(jià)值。
1.6.5 PostgreSQL 9.4中引入的新特性
9.4 版發(fā)布于 2014 年 9 月,主要包含以下新特性。
物化視圖特性的改進(jìn)
在 9.3 版中,刷新物化視圖期間會(huì)對(duì)其加鎖并禁止訪問,而加鎖時(shí)
間可能會(huì)比較長,這直接導(dǎo)致在生產(chǎn)環(huán)境中物化視圖的實(shí)用價(jià)值嚴(yán)重受
限。9.4 版中取消了刷新時(shí)的加鎖動(dòng)作,因此即使是正在被刷新的物化
視圖也可被訪問。但請(qǐng)注意:利用此特性的前提是物化視圖必須擁有一
個(gè)唯一索引。新增支持用于計(jì)算百分比的分析函數(shù)
新增了對(duì)
percentile_disc(不連續(xù)百分比)和
percentile_cont(連續(xù)百分比)這兩個(gè)分析函數(shù)的支持,須配合
WITHIN GROUP (ORDER BY...) 子句使用。PostgreSQL 專家 Hubert
Lubaczewski 在文章“Ordered Set Within Group Aggregates”中介紹了
ORDERED SET WITHIN GROUP 聚合運(yùn)算。在 9.5 之前的版本中,
PostgreSQL 并未提供過計(jì)算中位數(shù)的函數(shù)。這是有原因的。如果你對(duì)計(jì)
算中位數(shù)的相關(guān)算法有所了解的話,應(yīng)該知道這種算法中最后都會(huì)有一
個(gè)額外的類似于“平局加時(shí)賽”的計(jì)算步驟,這個(gè)步驟的存在使得將中位
數(shù)算法實(shí)現(xiàn)為聚合函數(shù)非常困難。9.5 版中引入的這兩個(gè)分析函數(shù)使用
了一種快速中位數(shù)估算算法,從而繞開了前述問題。我們將在 7.2.16 節(jié)
對(duì)這兩個(gè)函數(shù)進(jìn)行更深入的介紹。
支持對(duì)視圖更新操作的結(jié)果范圍進(jìn)行限制
創(chuàng)建視圖時(shí)支持 WITH CHECK OPTION 子句,其作用是確保在視圖
上執(zhí)行更新或者插入操作時(shí),修改后或者新插入的記錄仍然在本視圖可
見范圍內(nèi)。詳情請(qǐng)參見示例 7-3。
新增對(duì) JSONB 數(shù)據(jù)類型的支持
該數(shù)據(jù)類型是 JSON(JavaScript Object Notation)類型的二進(jìn)制存
儲(chǔ)版本。通過 JSONB 類型可以對(duì) JSON 格式的文檔數(shù)據(jù)建立索引,并
可加快對(duì)其內(nèi)部元素的訪問速度。詳細(xì)信息請(qǐng)參考 5.6 節(jié),同時(shí)可參考
這兩篇博客文章:“Introduce jsonb: A Structured Format for Storing
JSON”以及“JSONB: Wildcard Query”。
GIN 索引改進(jìn)GIN
索引在設(shè)計(jì)時(shí)已經(jīng)考慮了要適用于全文搜索、三連詞處
理、hstore 鍵值數(shù)據(jù)庫以及 jsonb 類型支持等場景。在很多情況下你
甚至可以把它當(dāng)作 B-樹索引的替代品,一般來說 GIN 索引與 B-樹的查
找效率相當(dāng),但占用空間更少。9.5 版中,GIN 索引的查詢速度被進(jìn)一
步提升。詳情請(qǐng)參見“GIN as a Substitute for Bitmap Indexes”這篇文章的
介紹。
支持更多 JSON 函數(shù)
具體包括
json_build_array、json_build_object、json_object、json_to_record
和 json_to_recordset 等幾個(gè)函數(shù)。
加速跨表空間的對(duì)象搬遷
支持使用以下語法輕松地將所有數(shù)據(jù)庫對(duì)象從一個(gè)表空間移動(dòng)到另
一個(gè)表空間:ALTER TABLESPACE old_space MOVE ALL TO
new_space;。
支持對(duì)返回的結(jié)果集中的記錄加上數(shù)字編號(hào)
現(xiàn)在可以為查詢結(jié)果中的記錄添加行號(hào)。行號(hào)用系統(tǒng)字段
ordinality(該字段是在 ANSI SQL 標(biāo)準(zhǔn)中定義的)表示。當(dāng)需要將
存儲(chǔ)為數(shù)組、hstore 鍵值對(duì)或者復(fù)合類型的非格式化數(shù)據(jù)轉(zhuǎn)換為格式
化記錄時(shí),該功能特別有用。以下是一個(gè)使用 hstore 的例子:
SELECT ordinality, key, value
FROM each('breed=>pug,cuteness=>high'::hstore) WITH ordinality;
支持通過執(zhí)行 SQL 命令來更改系統(tǒng)配置設(shè)置利用 ALTER system SET ... 語法,無須修改 postgresql.conf 文件
即可設(shè)置全局系統(tǒng)配置。postgresql.conf
文件具體的修改方法請(qǐng)參見
2.1.2
節(jié)。這也意味著用戶可以通過編程的方式動(dòng)態(tài)地調(diào)整系統(tǒng)配置
項(xiàng),但請(qǐng)注意:有的配置項(xiàng)修改后需要重啟數(shù)據(jù)庫才能生效。
觸發(fā)器功能增強(qiáng)
9.4 版中支持了對(duì)外部表創(chuàng)建觸發(fā)器。
數(shù)據(jù)行轉(zhuǎn)列能力增強(qiáng)
unnest 函數(shù)用于實(shí)現(xiàn)數(shù)據(jù)的行轉(zhuǎn)列操作,即將一個(gè)橫向的數(shù)組轉(zhuǎn)
換為縱向的一個(gè)字段的多行記錄。該函數(shù)可接受多個(gè)數(shù)組作為入?yún)ⅲ?/p>
個(gè)數(shù)組轉(zhuǎn)換后成為單獨(dú)的一列,即輸入幾個(gè)數(shù)組轉(zhuǎn)換后就有幾列。如果
每個(gè)數(shù)組的元素個(gè)數(shù)不一樣,9.4 版之前轉(zhuǎn)換后的結(jié)果是不可預(yù)知的,
9.4
版本后這種情況下轉(zhuǎn)換的結(jié)果是可預(yù)知的,會(huì)以最長的數(shù)組為標(biāo)
準(zhǔn),其他不足此長度的數(shù)組元素補(bǔ) null。
新增 ROWS FROM 語法
該語法可以將多個(gè)函數(shù)返回的結(jié)果集逐行拼接起來,最后作為一個(gè)
完整的結(jié)果集返回,因此即使這些結(jié)果集之間的元素個(gè)數(shù)不一致也沒關(guān)
系,如下例所示:
SELECT *
FROM ROWS FROM (jsonb_each('{"a":"foo1","b":"bar"}'::jsonb),
jsonb_each('{"c":"foo2"}'::jsonb))
x (a1,a1_val,a2_val);
支持動(dòng)態(tài)啟用后臺(tái)工作線程
當(dāng)使用 SQL 或 PostgreSQL 函數(shù)都無法實(shí)現(xiàn)所需要的功能時(shí),可以使用 C 語言編碼實(shí)現(xiàn)動(dòng)態(tài)后臺(tái)工作線程來達(dá)成目標(biāo)。9.4 版源碼的
contrib/worker_spi 目錄下實(shí)現(xiàn)了一個(gè)小型的示例,可供參考。1.7 數(shù)據(jù)庫驅(qū)動(dòng)程序
任何情況下,你都不可能脫離具體的業(yè)務(wù)系統(tǒng)而僅僅使用 PostgreSQL
數(shù)據(jù)庫本身,那顯然是無意義的。為了實(shí)現(xiàn) PostgreSQL 與業(yè)務(wù)系統(tǒng)之
間的交互,就需要借助數(shù)據(jù)庫驅(qū)動(dòng)程序。PostgreSQL 擁有大量免費(fèi)驅(qū)
動(dòng),支持各種編程語言和開發(fā)工具。此外,很多商業(yè)公司也以很低廉的
價(jià)格提供了各有特色的驅(qū)動(dòng)。目前比較流行的幾種開源驅(qū)動(dòng)如下。
PHP 驅(qū)動(dòng):PHP 語言廣泛應(yīng)用于 Web 開發(fā)領(lǐng)域,大多數(shù) PHP 發(fā)行
包都自帶了較老的 pgsql 驅(qū)動(dòng)或者是較新的 pdo_pgsql 驅(qū)動(dòng)。一般
來說這兩種驅(qū)動(dòng)默認(rèn)都會(huì)安裝,不過可能需要修改 php.ini 來決定
啟用哪一種。
JDBC 驅(qū)動(dòng):Java 開發(fā)所使用的 JDBC 驅(qū)動(dòng)一直是與最新版
PostgreSQL 同步更新的,可以從 PostgreSQL 官方站點(diǎn)下載。
.NET 驅(qū)動(dòng):.NET 框架(含微軟的官方版和 Mono 社區(qū)的開源版)
可使用 Npgsql 驅(qū)動(dòng)。目前該驅(qū)動(dòng)支持微軟 .NET 框架,包括微軟
Entity Framework 開發(fā)框架以及 Mono 開源 .NET 框架。
ODBC 驅(qū)動(dòng):如果需要從微軟 Access、Excel 或者其他支持 ODBC
的產(chǎn)品連接到 PostgreSQL,可從 PostgreSQL 官網(wǎng)下載 ODBC 驅(qū)
動(dòng),支持 32 位和 64 位兩個(gè)版本。
Libreoffice/OpenOffice 驅(qū)動(dòng):LibreOffice 3.5 及之后的版本中自帶
了 PostgreSQL 驅(qū)動(dòng),但 3.5 之前的版本以及 OpenOffice 是不帶
的,可以使用 JDBC 或者 SDBC 驅(qū)動(dòng)。更多細(xì)節(jié)請(qǐng)參見“OO Base
and PostgreSQL”這篇博文。
Python 驅(qū)動(dòng):Python 可通過多種驅(qū)動(dòng)訪問 PostgreSQL,目前
psycopg2
是最流行的一種。Python
的
Django
開發(fā)框架對(duì)
PostgreSQL 也有著良好的支持。如果你需要一個(gè)關(guān)系 - 對(duì)象映射工
具(即通常所說的 ORM 工具),可以考慮使用最廣泛的 SQLAlchemy 工具,著名的外部數(shù)據(jù)源封裝器開發(fā)平臺(tái) Multicorn 內(nèi)部
就使用了它。
Ruby 驅(qū)動(dòng):對(duì) Ruby 開發(fā)人員來說,請(qǐng)使用 rubygems pg 驅(qū)動(dòng)。
Perl 驅(qū)動(dòng):Perl 可以使用 DBI 和 DBD::Pg 驅(qū)動(dòng)。也可以使用由
CPAN 網(wǎng)站提供的 DBD::PgPP 驅(qū)動(dòng)。
Node.js 驅(qū)動(dòng):Node.js 是一個(gè) JavaScript 框架,可用于構(gòu)建可擴(kuò)展
的網(wǎng)絡(luò)應(yīng)用。該平臺(tái)目前支持兩種 PostgreSQL 驅(qū)動(dòng):一種是 Node
Postgres,該驅(qū)動(dòng)可以選擇是否綁定本地
libpq
庫,而且基于純
JavaScript(無須編譯);另一種是 Node-DBI。1.8 如何獲得幫助
在使用 PostgreSQL 的過程中,你遲早會(huì)需要尋求幫助,而且這一天往
往會(huì)比預(yù)期來得早。我們希望你能夠盡早了解到求助的途徑。我們最為
推薦的途徑是郵件列表,不管你是 PostgreSQL 的新用戶還是老用戶,
郵件列表都能為你解答技術(shù)問題。可以先打開 PostgreSQL 郵件列表頁
面。如果你是新手,那么訂閱 PGSQL-General 這個(gè)郵件列表是最合適
的。如果你認(rèn)為自己發(fā)現(xiàn)了 PostgreSQL 的 bug,那么打開“PostgreSQL
故障報(bào)告”這個(gè)頁面,上面會(huì)告訴你具體如何操作1.9 PostgreSQL的主要衍生版本
PostgreSQL 使用了 MIT/BSD 風(fēng)格的許可證,任何人都可以合法地對(duì)其
修改并二次傳播,因此對(duì)于那些想創(chuàng)建自己數(shù)據(jù)庫分支的人來說,
PostgreSQL 是絕佳的選擇。在過去的很多年間,有很多團(tuán)隊(duì)創(chuàng)建了自己
的 PostgreSQL 分支版本,并且對(duì)社區(qū)也做出了相應(yīng)的回饋,有的把自
己的修改貢獻(xiàn)回了 PostgreSQL 的主干代碼,有的對(duì)社區(qū)給予了資金支
持。訪問 https://wiki.postgresql.org/wiki/PostgreSQL_derived_databases 這
個(gè)地址,就可以看到 PostgreSQL 數(shù)據(jù)庫的所有衍生產(chǎn)品。
很多流行的分支版本是商業(yè)化的閉源軟件。比如目前數(shù)據(jù)倉庫領(lǐng)域使用
很廣泛的 Netezza 就是源自 PostgreSQL。亞馬遜公司的 Redshift 數(shù)據(jù)倉
庫事實(shí)上是 PostgreSQL 的一個(gè)分支的分支。亞馬遜還有其他兩個(gè)與原
生 PostgreSQL 血緣關(guān)系較近的產(chǎn)品:Amazon RDS for PostgreSQL 和
Amazon Aurora for PostgreSQL。這兩個(gè)產(chǎn)品會(huì)與 PostgreSQL 開源版本
的主干代碼保持同源,并確保與原生 PostgreSQL 提供完全相同的 SQL
語法,同時(shí)額外提供了更強(qiáng)的管理功能并在速度方面做了一些優(yōu)化。
EnterpriseDB 公司推出的 PostgreSQL Advanced Plus 也是以 PostgreSQL
為基礎(chǔ),另外增加了對(duì)于 Oracle 語法和特性的兼容支持,以吸引原
Oracle 用戶。EnterpriseDB 公司向 PostgreSQL 社區(qū)提供了資金和開發(fā)力
量的支持,對(duì)此我們表示感謝。他們的 Postgres Plus Advanced Server 產(chǎn)
品在版本更新節(jié)奏上也一直是密切跟進(jìn)最新的 PostgreSQL 穩(wěn)定版的。
Postgre-X2、Postgres-XL
和
GreenPlum
是三款還處于發(fā)展初期的
PostgreSQL 開源衍生產(chǎn)品,其中 GreenPlum 曾經(jīng)有一段時(shí)間是閉源的。
這三款產(chǎn)品的目標(biāo)都是處理大規(guī)模數(shù)據(jù)分析和復(fù)制工作。
PostgreSQL 之所以衍生版本眾多,部分原因是主干版本對(duì)于一些小眾的需求可能不會(huì)及時(shí)支持,另外主干版本的發(fā)布節(jié)奏也不能滿足所有人的
要求,那么自己拉出來一個(gè)分支版本提前進(jìn)行修改和測試就是更好的選
擇。很多這種分支版本中開發(fā)出來的新特性最終都匯合到了主干,比如
2nd Quadrant 公司支持多主和雙向復(fù)制特性的 BDR 產(chǎn)品分支中的邏輯
復(fù)制功能就被匯合入了主干,用于強(qiáng)化 PostgreSQL 原生的復(fù)制功能。
PostgreSQL-XL 中開發(fā)的一些并行化特性將來也可能會(huì)合入 PostgreSQL
主干中。
Citus 是一個(gè)支持實(shí)時(shí)大數(shù)據(jù)處理和并行查詢功能的 PostgreSQL 分支,
從 PostgreSQL 9.5 開始它被改造成了 PostgreSQL 的一個(gè)擴(kuò)展包,使用
起來更加方便。
Google 最近發(fā)布了它的 Google Cloud SQL for PostgreSQL 產(chǎn)品,目前還
處在 beta 測試階段。






