問題來了,PostgreSQL的好處都有啥?
PostgreSQL的Slogan是“世界上最先進的開源關(guān)系型數(shù)據(jù)庫”,但我覺得這口號不夠清晰,啥叫‘先進’?而且一看就是在懟MySQL那個“世界上最流行的開源關(guān)系型數(shù)據(jù)庫”的口號,有碰瓷之嫌。要我說最能生動體現(xiàn)PG特色的描述應(yīng)該是:一專多長的全棧數(shù)據(jù)庫,一招鮮吃遍天。
全棧數(shù)據(jù)庫
成熟的應(yīng)用可能會用到許許多多的數(shù)據(jù)組件(功能):緩存,OLTP,OLAP/批處理/數(shù)據(jù)倉庫,流處理/消息隊列,搜索索引,NoSQL/文檔數(shù)據(jù)庫,地理數(shù)據(jù)庫,空間數(shù)據(jù)庫,時序數(shù)據(jù)庫,圖數(shù)據(jù)庫。傳統(tǒng)的架構(gòu)選型呢,可能會組合使用多種組件,典型的如:Redis + MySQL + Greenplum/Hadoop + Kafuka/Flink + ElasticSearch,一套組合拳基本能應(yīng)付大多數(shù)需求了。不過比較令人頭大的就是異構(gòu)系統(tǒng)集成了:大量的代碼都是重復(fù)繁瑣的搬磚代碼,干著把數(shù)據(jù)從A組件搬運到B組件的事情。
在這里,MySQL就只能扮演OLTP關(guān)系型數(shù)據(jù)庫的角色,但如果是PostgreSQL,就可以身兼多職,One handle them all,比如:
- OLTP:事務(wù)處理是PostgreSQL的本行
- OLAP:citus分布式插件,ANSI SQL兼容,窗口函數(shù),CTE,CUBE等高級分析功能,任意語言寫UDF
- 流處理:PipelineDB擴展,Notify-Listen,物化視圖,規(guī)則系統(tǒng),靈活的存儲過程與函數(shù)編寫
- 時序數(shù)據(jù):timescaledb時序數(shù)據(jù)庫插件,分區(qū)表,BRIN索引
- 空間數(shù)據(jù):PostGIS擴展(殺手锏),內(nèi)建的幾何類型支持,GiST索引。
- 搜索索引:全文搜索索引足以應(yīng)對簡單場景;豐富的索引類型,支持函數(shù)索引,條件索引
- NoSQL:JSON,JSONB,XML,HStore原生支持,至NoSQL數(shù)據(jù)庫的外部數(shù)據(jù)包裝器
- 數(shù)據(jù)倉庫:能平滑遷移至同屬Pg生態(tài)的GreenPlum,DeepGreen,HAWK等,使用FDW進行ETL
- 圖數(shù)據(jù):遞歸查詢
- 緩存:物化視圖
以擴展作六器,禮天地四方。
以FDW禮天,以Greenplum禮地,
以Citus禮東方,以Timescale禮南方,
以PostGIS禮西方,以Pipeline禮北方。
——《周禮·辟吉》
在探探的舊版架構(gòu)中,整個系統(tǒng)就是圍繞PostgreSQL設(shè)計的。幾百萬日活,幾百萬全局DB-TPS,幾百TB數(shù)據(jù)的規(guī)模下,數(shù)據(jù)組件只用了PostgrSQL。獨立的數(shù)倉,消息隊列和緩存都是后來才引入的。而且這只是驗證過的規(guī)模量級,進一步壓榨PG是完全可行的。
因此,在一個很可觀的規(guī)模內(nèi),PostgreSQL都可以扮演多面手的角色,一個組件當(dāng)多種組件使。雖然在某些領(lǐng)域它可能比不上專用組件,至少都做的都還不賴。而單一數(shù)據(jù)組件選型可以極大地削減項目額外復(fù)雜度,這意味著能節(jié)省很多成本。它讓十個人才能搞定的事,變成一個人就能搞定的事。
對絕大多數(shù)應(yīng)用而言,終其生命周期都不會有超出Pg能力范圍之外的數(shù)據(jù)量級。為了不需要的規(guī)模而設(shè)計是白費功夫,實際上這屬于過早優(yōu)化的一種形式。 此外,只有當(dāng)沒有單個軟件能滿足你的所有需求時,才會存在分拆與集成的利弊權(quán)衡。集成多種異構(gòu)技術(shù)是相當(dāng)棘手的工作,如果真有那么一樣技術(shù)可以滿足你所有的需求,那么使用該技術(shù)就是最佳選擇,而不是試圖用多個組件來重新實現(xiàn)它。
當(dāng)業(yè)務(wù)規(guī)模增長到一定量級時,可能不得不使用基于微服務(wù)/總線的架構(gòu),將數(shù)據(jù)庫的功能分拆為多個組件。但PostgreSQL的存在極大地推后了這個權(quán)衡到來的閾值,而且分拆之后依然能繼續(xù)發(fā)揮重要作用。
運維友好
當(dāng)然除了功能強大之外,Pg的另外一個重要的優(yōu)勢就是運維友好。有很多非常實用的特性:
- DDL能放入事務(wù)中,刪表,TRUNCATE,創(chuàng)建函數(shù),索引,都可以放在事務(wù)里原子生效,或者回滾。
- 這就能進行很多騷操作,比如在一個事務(wù)里通過RENAME,完成兩張表的王車易位。
- 能夠并發(fā)地創(chuàng)建、刪除索引,添加非空字段,重整索引與表(不鎖表)。
- 這意味著可以隨時在線上不停機進行重大的模式變更,按需對索引進行優(yōu)化。
- 復(fù)制方式多樣:段復(fù)制,流復(fù)制,觸發(fā)器復(fù)制,邏輯復(fù)制,插件復(fù)制等等。
- 這使得不停服務(wù)遷移數(shù)據(jù)變得相當(dāng)容易:復(fù)制,改讀,改寫三步走,線上遷移穩(wěn)如狗。
- 提交方式多樣:異步提交,同步提交,法定人數(shù)同步提交。
- 這意味著Pg允許在C和A之間做出權(quán)衡與選擇,例如交易庫使用同步提交,普通庫使用異步提交。
- 系統(tǒng)視圖非常完備,做監(jiān)控系統(tǒng)相當(dāng)簡單。
- FDW的存在讓ETL變得無比簡單,一行SQL就能解決。
- FDW可以方便地讓一個實例訪問其他實例的數(shù)據(jù)或元數(shù)據(jù)。在跨分區(qū)操作,數(shù)據(jù)庫監(jiān)控指標(biāo)收集,數(shù)據(jù)遷移等場景中妙用無窮。同時還可以對接很多異構(gòu)數(shù)據(jù)系統(tǒng)。
還有很多功能,就不一一列舉了。
生態(tài)健康
PostgreSQL的生態(tài)也很健康,社區(qū)相當(dāng)活躍。
相比MySQL,PostgreSQL的一個巨大的優(yōu)勢就是協(xié)議友好。PG采用類似BSD/MIT的PostgreSQL協(xié)議,差不多理解為只要別打著Pg的旗號出去招搖撞騙,隨便你怎么搞,換皮出去賣都行。君不見多少國產(chǎn)數(shù)據(jù)庫,或者不少“自研數(shù)據(jù)庫”實際都是Pg的換皮或二次開發(fā)產(chǎn)品。
當(dāng)然,也有很多衍生產(chǎn)品會回饋主干,比如timescaledb,pipelinedb, citus 這些基于PG的“數(shù)據(jù)庫”,最后都變成了原生PG的插件。很多時候你想實現(xiàn)個什么功能,一搜就能找到對應(yīng)的插件或?qū)崿F(xiàn)。開源嘛,還是要講一些情懷的。
Pg的代碼質(zhì)量相當(dāng)之高,注釋寫的非常清晰。C的代碼讀起來有種Go的感覺,代碼都可以當(dāng)文檔看了。能從中學(xué)到很多東西。相比之下,其他數(shù)據(jù)庫,比如MongoDB,看一眼我就放棄了讀下去的興趣。
而MySQL呢,社區(qū)版采用的是GPL協(xié)議,這其實挺蛋疼的。要不是GPL傳染,怎么會有這么多基于MySQL改的數(shù)據(jù)庫開源出來呢?而且MySQL還在烏龜殼的手里,讓自己的蛋蛋攥在別人手中可不是什么明智的選擇,更何況是業(yè)界毒瘤呢?Facebook修改React協(xié)議的風(fēng)波就算是一個前車之鑒了。
問題
當(dāng)然,要說有什么缺點或者遺憾,那還是有幾個的:
- 因為使用了MVCC,數(shù)據(jù)庫需要定期VACUUM,需要定期維護表和索引避免膨脹導(dǎo)致性能下降。
- 沒有很好的開源集群監(jiān)控方案(或者太丑!),需要自己做。
- 慢查詢?nèi)罩竞推胀ㄈ罩臼腔煸谝黄鸬?,需要自己解析處理?/li>
- 官方Pg沒有很好用的列存儲,對數(shù)據(jù)分析而言算一個小遺憾。
當(dāng)然都是些無關(guān)痛癢的小毛小病,不過真正的問題可能和技術(shù)無關(guān)……
說到底,MySQL確實是最流行的開源關(guān)系型數(shù)據(jù)庫,沒辦法,寫Java的,寫PHP的,很多人最開始用的都是MySQL…,所以Pg招人相對困難是一個事實,很多時候只能自己培養(yǎng)。不過看DB Engines上的流行度趨勢,未來還是很光明的。