最近,小編在知乎上看到這樣一個(gè)問(wèn)題:
PostgreSQL也很強(qiáng)大,為何在中國(guó)大陸MySQL成為主流,PostgreSQL屈居二線呢?
PostgreSQL能否替代MySQL?我感覺(jué)PostgreSQL非常強(qiáng)大,很多地方超過(guò)了MySQL。
舉幾個(gè)例子:
1.豐富的數(shù)據(jù)類(lèi),支持?jǐn)?shù)組、字典、json、序列號(hào)
2.強(qiáng)大的審計(jì)函數(shù)
3.強(qiáng)大的索引,易于sql調(diào)優(yōu)
PostgreSQL在許多地方,有MySQL無(wú)法比擬的優(yōu)勢(shì)。但是在中國(guó)大陸,許多公司的核心業(yè)務(wù)庫(kù),都是MySQL,PostgreSQL則屈居二線,作為審計(jì)類(lèi)的數(shù)據(jù)庫(kù)來(lái)使用。
為什么不讓PostgreSQL來(lái)扛大梁呢,而要用MySQL,PostgreSQL不合適么?
MySQL和PostgreSQL在功能上各有千秋,為什么沒(méi)能在業(yè)界中形成“平分天下”的局面呢?小編精選了幾位知乎網(wǎng)友的精彩回答,分享給大家學(xué)習(xí)交流(仁者見(jiàn)仁,智者見(jiàn)智,勿引戰(zhàn)~):
以下均為個(gè)人感覺(jué),沒(méi)做過(guò)統(tǒng)計(jì),就當(dāng)個(gè)參考吧。
MySQL和Postgres的早期完全是兩個(gè)極端。MySQL更像是個(gè)“基本上滿(mǎn)足關(guān)系數(shù)據(jù)庫(kù)語(yǔ)法的大號(hào)KV”,對(duì)關(guān)系型數(shù)據(jù)庫(kù)的高級(jí)功能支持得很不好。我入行時(shí)接觸的MySQL 5.1和MyISAM存儲(chǔ)引擎,不支持ACID,但有如下幾點(diǎn)在當(dāng)時(shí)的互聯(lián)網(wǎng)公司看來(lái)是非常合適:1. 互聯(lián)網(wǎng)公司為了擴(kuò)展,長(zhǎng)期的經(jīng)驗(yàn)是,僅僅把數(shù)據(jù)庫(kù)當(dāng)作是一個(gè)“存儲(chǔ)”,而非存儲(chǔ)+核心數(shù)據(jù)邏輯的計(jì)算節(jié)點(diǎn)。大量的計(jì)算都在業(yè)務(wù)服務(wù)器上進(jìn)行,而業(yè)務(wù)服務(wù)器可以無(wú)限水平擴(kuò)展,無(wú)需擔(dān)心有狀態(tài)的數(shù)據(jù)遷移問(wèn)題;2. 因?yàn)闆](méi)有提供很多高級(jí)功能和數(shù)據(jù)一致性的保障,MySQL對(duì)于簡(jiǎn)單的sql支持的反而更加直接,在速度上有很大的優(yōu)勢(shì);3. 對(duì)于OLTP,完全不需要復(fù)雜的數(shù)據(jù)處理功能。簡(jiǎn)單的select ... from ... where id = xxx; insert into xxx;update xxx set xxx=xxx where id = xxxx是OLTP的主流功能?;谶@些功能的ORM的出現(xiàn)大大提高了生產(chǎn)效率;對(duì)于OLAP,盡管Postgres查詢(xún)分析功能很強(qiáng),但是一般互聯(lián)網(wǎng)公司的數(shù)據(jù)量實(shí)在太大,用Postgres這種數(shù)據(jù)庫(kù)根本無(wú)法處理。通常會(huì)用MapReduce、Hive、Pig等大數(shù)據(jù)處理工具來(lái)分析;4. 多線程模型,天然對(duì)高并發(fā)支持良好。而pg一直是多進(jìn)程模型。進(jìn)程的創(chuàng)建會(huì)更慢,更耗內(nèi)存。雖然有些PG的連接池方案,但是MySQL在這方面“開(kāi)箱即用”;5. Postgres早期并不支持“邏輯復(fù)制”。物理復(fù)制意味著存儲(chǔ)格式的細(xì)節(jié)完全暴露,不兼容的版本無(wú)法直接組成主從同步,于是無(wú)法做滾動(dòng)升級(jí)。這就意味著在升級(jí)數(shù)據(jù)庫(kù)時(shí),必須停服,把整個(gè)集群升級(jí)后再恢復(fù)。而MySQL從一開(kāi)始就是邏輯復(fù)制(這其實(shí)是由于MySQL一直是server和存儲(chǔ)引擎分層的架構(gòu),邏輯復(fù)制發(fā)生在server層)。這個(gè)缺陷會(huì)讓Postgres的運(yùn)營(yíng)不受業(yè)務(wù)開(kāi)發(fā)者的待見(jiàn)。誰(shuí)也不希望自己的業(yè)務(wù)停服。反過(guò)來(lái)再看Postgres的優(yōu)點(diǎn),會(huì)發(fā)現(xiàn)對(duì)于OLTP并沒(méi)有太大的吸引力:1. 豐富的數(shù)據(jù)類(lèi)型:通常用處不大,常用類(lèi)型足夠了。如果有復(fù)雜類(lèi)型,業(yè)務(wù)上自己序列化,存儲(chǔ)成varchar就行。可以用json,PB,avro等。序列化反序列化都發(fā)生在業(yè)務(wù)服務(wù)器,更好維護(hù)和優(yōu)化;2. 強(qiáng)大的審計(jì)函數(shù):互聯(lián)網(wǎng)早期活下來(lái)是一切,審計(jì)并不是核心需求(通常需要嚴(yán)格審計(jì)的領(lǐng)域早就會(huì)用Oracle/msSQL,不差錢(qián));3. 強(qiáng)大的索引:Postgres的自定義索引功能很強(qiáng)大。但是對(duì)于MySQL,關(guān)鍵的幾列有索引就夠了,不需要復(fù)雜的高級(jí)索引。我承認(rèn)早期MySQL的查詢(xún)優(yōu)化器智商堪憂(yōu),但如果要改,一句explain,然后force index也就是了,對(duì)于開(kāi)發(fā)人員簡(jiǎn)單直接。有一段時(shí)間LBS很流行,當(dāng)時(shí)MongoDB很潮地直接支持了空間索引。當(dāng)時(shí)大家紛紛“NoSQL”,就更不會(huì)看Postgres一眼。然后到了大概2015年,MySQL 5.7也支持空間索引了。4. Posgres的MVCC實(shí)現(xiàn)牛不?牛。serial snapshot isolation是很強(qiáng),但是到了需要變更數(shù)據(jù)嚴(yán)格一致的時(shí)候,select ... for update又不是不能用:)5. 對(duì)于序列號(hào),sequence是很好。但是互聯(lián)網(wǎng)公司對(duì)于簡(jiǎn)單場(chǎng)景用auto increment,對(duì)于生產(chǎn)場(chǎng)景就直接用分布式序列號(hào)生成服務(wù)了。Postgres的序列號(hào)產(chǎn)生器~偏雞肋。6. Postgres的全文索引很強(qiáng),但強(qiáng)得過(guò)ES?強(qiáng)得過(guò)專(zhuān)門(mén)定制的搜索引擎系統(tǒng)?要知道搜索業(yè)務(wù)最關(guān)鍵的是把“最匹配搜索人需要的搜索結(jié)果返回出來(lái)”,而不是僅僅“能搜到一堆不分主次但滿(mǎn)足關(guān)鍵字匹配的結(jié)果”。因此早期MySQL變成了事實(shí)上的互聯(lián)網(wǎng)企業(yè)OLTP的事實(shí)標(biāo)準(zhǔn)。不管干啥業(yè)務(wù),MySQL都不可或缺。在行業(yè)里跳槽來(lái)跳槽去的程序員普遍對(duì)MySQL也更熟悉。大量圍繞MySQL的商業(yè)服務(wù)都成為了行業(yè)主流。新一代分布式數(shù)據(jù)庫(kù),像TiDB為了吸引用戶(hù),首先要做的是“兼容MySQL的語(yǔ)法”。再往后,MySQL增加了更多“關(guān)系型數(shù)據(jù)庫(kù)該有的”功能,比如完全支持ACID的innodb成為默認(rèn)存儲(chǔ)引擎,比如5.7的json原生支持,8.0的window function/CTE。而Postgres也增加了更多的“互聯(lián)網(wǎng)功能”,但是時(shí)機(jī)已經(jīng)過(guò)去了。大家MySQL跑著業(yè)務(wù)好好的,而切換數(shù)據(jù)庫(kù)絕對(duì)不是僅僅像某些ORM標(biāo)榜的換一個(gè)Dialect就行的,整個(gè)編程模型,性能表現(xiàn),運(yùn)維工具和流程都要有巨大的變化。如非必要,犯不著為了一個(gè)“most advanced”的標(biāo)語(yǔ)去折騰,更不會(huì)為了數(shù)據(jù)庫(kù)愛(ài)好者的情懷做傷害利益的事情。2號(hào)知乎網(wǎng)友:羅詩(shī)亞我已經(jīng)不寫(xiě)代碼、做技術(shù)管理一段時(shí)間了,但是有些支持工程師做技術(shù)選型的經(jīng)驗(yàn),根據(jù)業(yè)務(wù)上的需求來(lái)聊一聊吧。這里一半是我們技術(shù)選型時(shí)TL告訴我的,一半是我個(gè)人代碼實(shí)踐的經(jīng)驗(yàn)。數(shù)據(jù)庫(kù)這種早期用了就基本不能換的東西是有滯后性的,你看到現(xiàn)在MySQL的現(xiàn)狀,是“5年前MySQL是國(guó)內(nèi)幾乎唯一選擇”造成的情況。5年前Postgres就已經(jīng)在歐美初創(chuàng)項(xiàng)目里比較受歡迎了,國(guó)內(nèi)公司數(shù)據(jù)量、體量是國(guó)外公司無(wú)法比的,畢竟用戶(hù)人數(shù)多,隨便都上億,而且國(guó)外這幾年新項(xiàng)目活得好的公司都是B2B,有幾十萬(wàn)上百萬(wàn)用戶(hù)量就很不錯(cuò)了。Postgres有scaling issue(擴(kuò)展問(wèn)題?這個(gè)詞中文怎么說(shuō)),一個(gè)表2-3T就不行了,不做大量?jī)?yōu)化查詢(xún)速度就以秒開(kāi)始做單位了,這是云數(shù)據(jù)庫(kù)提供商不會(huì)告訴你的。他們只會(huì)告訴你Postgres的優(yōu)點(diǎn)。題外話,NoSQL也有類(lèi)似的壞處。但是除非在生產(chǎn)環(huán)境中踩過(guò)坑,沒(méi)有人會(huì)告訴你的。在技術(shù)社區(qū)里噴某個(gè)解決方案不行是會(huì)被鄙視的,特別是大公司,有這種體量業(yè)務(wù)的工程師是沒(méi)時(shí)間跟你說(shuō)這種掃興的話的。Postgres的好處之一是有好幾年給新語(yǔ)言的ORM比MySQL成熟,對(duì)全棧工程師更友好。歐美的全棧工程師一般是腳本語(yǔ)言后端(Node、RoR、Python)加上前端。國(guó)內(nèi)更流行的是強(qiáng)類(lèi)型語(yǔ)言(Java)后端,一般不會(huì)同時(shí)前端的,Java + MySQL是真香。歐美這種全棧工程師的弱點(diǎn)就是對(duì)后端沒(méi)有那么深的理解,這里就不細(xì)聊了。前幾年不需要運(yùn)維支持就能部署的云服務(wù)提供商(Digital Ocean、Heroku)只支持Postgres。同上,全棧工程師一般是沒(méi)有運(yùn)維能力的。EC2上給你裝個(gè)MySQL?RDS的文檔能看懂就很不錯(cuò)了好嗎~MySQL對(duì)于你說(shuō)的那些Postgres優(yōu)點(diǎn),都在國(guó)內(nèi)有業(yè)界已經(jīng)驗(yàn)證過(guò),實(shí)施經(jīng)驗(yàn)人數(shù)也很多的最佳解決方案。而且那些優(yōu)點(diǎn),是工程師做得爽而已,跟業(yè)務(wù)沒(méi)啥實(shí)質(zhì)性的關(guān)系。而踩過(guò)Postgres坑的這種人招不到,才是阻礙業(yè)務(wù)的第一大要素。最后,為什么都是data類(lèi)才用PG,因?yàn)閐ata不是業(yè)務(wù)組,運(yùn)維支持力度沒(méi)那么大,也沒(méi)有實(shí)時(shí)性能上的壓力,上面的壞處不是什么壞處,好處卻是可見(jiàn)的,能夠提高開(kāi)發(fā)速度的。寫(xiě)得不對(duì)的請(qǐng)勿噴,哈哈。這可能還真的跟PHP有點(diǎn)關(guān)系,PHP很早的版本就有內(nèi)置的mysql支持,很多Linux發(fā)行版都可以一鍵安裝LAMP套件(Apache + MySQL + PHP),基本不用配置就可以開(kāi)始用。其實(shí)國(guó)內(nèi)PHP流行的時(shí)候已經(jīng)有pgsql的支持了,但是習(xí)慣和早期沿襲的資料的影響仍然是巨大的。因?yàn)镸ySQL用得多,自然熟悉MySQL的DBA也多,熟悉pgsql的DBA少,也就進(jìn)一步影響了其它語(yǔ)言的選型。對(duì)于當(dāng)時(shí)的大部分開(kāi)發(fā)者和公司來(lái)說(shuō),PGSQL的那些高級(jí)功能反正也不會(huì)用,自然就跟不存在沒(méi)什么兩樣。4號(hào)知乎網(wǎng)友:聿明leslie說(shuō)說(shuō)鄙人的見(jiàn)解。從技術(shù)而言,PG 功能豐富,SQL 支持得很完備,強(qiáng)大的數(shù)據(jù)類(lèi)型,嚴(yán)謹(jǐn)?shù)年P(guān)系模型,很難從關(guān)系模型去找出PG的不合理之處,多年積累,連全文索引詞庫(kù)都非常豐富,據(jù)說(shuō)對(duì)于一些簡(jiǎn)單的搜索,都可以擺脫搜索引擎了,優(yōu)化器做得很好,在代價(jià)選擇上 PG 實(shí)現(xiàn)了基因算法,這一點(diǎn)連Oracle 也沒(méi)有做到。讀過(guò)一部分 PG 的代碼和 MySQL 的代碼,對(duì)比起來(lái),PG 的代碼寫(xiě)得非常工整,注釋也很細(xì)致,真的可以稱(chēng)得上code 教科書(shū)級(jí)別的工程,一定是一幫有情懷的coder 寫(xiě)出來(lái)的,對(duì)比起來(lái),MySQL 就是一坨……可是這個(gè)問(wèn)題是一個(gè)工程性問(wèn)題,就不要用這些方面來(lái)衡量一個(gè)工程問(wèn)題!歷史總是時(shí)勢(shì)造英雄,看看MySQL 火起來(lái)的那段時(shí)間,正是互聯(lián)網(wǎng)爆發(fā)式增長(zhǎng)的那幾年。由于PG 豐富的功能,所以它顯得太重了,多進(jìn)程并發(fā),再加上早期的存儲(chǔ)做得不夠好,太吃資源。在那個(gè)時(shí)代,內(nèi)存和存儲(chǔ)都是比較昂貴的資源,早期的PG 性能也不太好,由于關(guān)系模型支持得很好,用起來(lái)會(huì)有諸多限制,學(xué)習(xí)成本會(huì)比較高。比起這些,MySQL 要輕量很多,到現(xiàn)在這也是它的一個(gè)優(yōu)點(diǎn),在互聯(lián)網(wǎng)這個(gè)特定的場(chǎng)景中,大家為了追求快速迭代和拓展性,使用的 SQL 功能不會(huì)太多,都?jí)蛴谩?/span>而PG 由于更嚴(yán)謹(jǐn)?shù)?SQL 關(guān)系模型,很多用法都限制得比較死,MySQL 卻要靈活很多,你的劣勢(shì)就出來(lái)了。這個(gè)讓用戶(hù)用起來(lái)很爽,但是對(duì)于兼容 MySQL 的兼容實(shí)現(xiàn)者很痛苦;有些 feature 在特定的場(chǎng)景中用起很便利,但是在通用的模型中卻禁不起推敲,要不要兼容它呢?但用戶(hù)很難感知到這些,除非測(cè)試去亂試,一般人不會(huì)那么無(wú)聊,這就是工程上的權(quán)衡。很難說(shuō)誰(shuí)好誰(shuí)壞。而用的人多了,相關(guān)的使用經(jīng)驗(yàn)會(huì)匯總到社區(qū),形成部署方案、工具等,這又是工程中的正反饋。在江湖中,有幾個(gè)身負(fù)各項(xiàng)絕技的大俠最后成了將軍和皇帝的?5號(hào)知乎網(wǎng)友:flaneur感覺(jué)是在幾個(gè)互聯(lián)網(wǎng)痛點(diǎn)的時(shí)間窗口沒(méi)趕上,蠻可惜的。之前 uber 有一篇文章:Why Uber Engineering Switched from Postgres to MySQL(link.zhihu.com/?target=https%3A//eng.uber.com/Postgres-to-MySQL-migration/)里面提到的幾個(gè)問(wèn)題現(xiàn)在我猜應(yīng)該有解決,但是時(shí)間點(diǎn)晚了,比如:- 邏輯復(fù)制:之前 uber 用的物理復(fù)制,master 上一個(gè) bug 導(dǎo)致數(shù)據(jù)損壞一個(gè) bit 寫(xiě)錯(cuò)了,所有的從跟著壞。
- Replica 事務(wù)糙:猜 Replica 的事務(wù)快照是怎么實(shí)現(xiàn)的?開(kāi)一個(gè)事務(wù)快照 == 停止主從復(fù)制。
寫(xiě)放大 + Replication 流量放大:與 MySQL 二級(jí)索引不同,Postgres 的索引指向的也是個(gè)物理位置,寫(xiě)入數(shù)據(jù)時(shí),即使索引的值未變化,也要更新索引指向的物理地址,存在一點(diǎn)寫(xiě)放大,在物理復(fù)制的場(chǎng)景下,寫(xiě)放大 == 流量放大。
連接管理:Postgres 一個(gè)連接一個(gè)進(jìn)程,這時(shí)候你才想起來(lái)線程竟然是個(gè)輕量的東西。
MySQL 給人的感覺(jué)就是「我啥都挫,要啥特性沒(méi)啥特性,事務(wù)都用起來(lái)沒(méi)多少年,但是我十、二十年前就有主從邏輯復(fù)制跟 MHA」。
"為何MySQL在大陸成為主流,PostgreSQL屈居二線呢?"歡迎在留言區(qū)交流,留下你的觀點(diǎn)~
來(lái)源丨知乎:zhihu.com/question/31955622
該文章在 2024/3/15 15:17:44 編輯過(guò)