SQL必須消失的九個(gè)理由,你認(rèn)可嗎?
譯文譯者 | 晶顏
審校 | 重樓
考慮到SQL的流行和成功,本文更像是一個(gè)悖論研究。SQL可能笨拙而冗長,但開發(fā)人員經(jīng)常發(fā)現(xiàn)它是提取所需數(shù)據(jù)的最簡單、最直接的方法。當(dāng)查詢寫入正確時(shí),它可以像閃電一樣快,而當(dāng)查詢出錯(cuò)時(shí),它又會(huì)慢得驚人。它已經(jīng)存在了幾十年,但新功能一直在不斷增加。
這些矛盾并不重要,因?yàn)槭袌鲆呀?jīng)表明:SQL是許多人的首選,即使有更新的、更強(qiáng)大的選項(xiàng)。從最小的網(wǎng)站到最大的大型公司,各地的開發(fā)人員都知道SQL。他們依靠它來組織所有的數(shù)據(jù)。
SQL的表格模型如此流行,以至于許多非SQL項(xiàng)目最終都添加了SQLish接口,因?yàn)橛脩粜枰?/span>甚至是“NoSQL”運(yùn)動(dòng)——其發(fā)明是為了擺脫舊的范式——最終似乎也敗給了SQL。
SQL的局限性可能不足以將其徹底拋棄。開發(fā)人員也可能永遠(yuǎn)不會(huì)著手將所有數(shù)據(jù)從SQL中遷移出去。但是SQL的問題是真實(shí)存在的,足以給開發(fā)人員帶來壓力,增加延遲,甚至需要對(duì)某些項(xiàng)目進(jìn)行重新設(shè)計(jì)。
下面是我們希望放棄SQL的9個(gè)原因,盡管我們知道這可能做不到。
表格不能擴(kuò)展
關(guān)系模型鐘情于表格,所以我們一直在構(gòu)建它。這對(duì)于小型甚至正常大小的數(shù)據(jù)庫來說還好,但面對(duì)真正的大規(guī)模數(shù)據(jù)庫,這個(gè)模型就會(huì)崩潰。
有些人試圖通過將新舊結(jié)合起來來解決問題,比如將分片集成到舊的開源數(shù)據(jù)庫中。添加層似乎可以使數(shù)據(jù)更易于管理,并提供無限的規(guī)模。但這些增加的層可能隱藏危險(xiǎn)。根據(jù)分片中存儲(chǔ)的數(shù)據(jù)量,SELECT或JOIN的處理時(shí)間可能會(huì)有很大的不同。
分片還迫使數(shù)據(jù)庫管理員(DBA)考慮數(shù)據(jù)可能存儲(chǔ)在不同的機(jī)器上,甚至可能存儲(chǔ)在不同的地理位置上的可能性。沒有經(jīng)驗(yàn)的管理員在開始跨表搜索時(shí),如果沒有意識(shí)到數(shù)據(jù)存儲(chǔ)在不同的位置,可能會(huì)感到困惑。該模型有時(shí)會(huì)將位置從視圖中抽象出來。
一些AWS機(jī)器配備了24TB的RAM,因?yàn)橐恍?shù)據(jù)庫用戶需要這么多。他們在SQL數(shù)據(jù)庫中有這么多數(shù)據(jù),而且這樣能夠運(yùn)行得更好。
SQL不是JSON或XML原生的
SQL可能是一種“常青樹式”的語言,但它并不特別適合JSON、YAML和XML等較新的數(shù)據(jù)交換格式。所有這些都支持比SQL更分層、更靈活的格式。SQL數(shù)據(jù)庫的核心仍然停留在關(guān)系模型中,充斥著各種表格。
市場會(huì)想方設(shè)法掩蓋這種常見的抱怨。使用正確的粘合代碼添加不同的數(shù)據(jù)格式(如JSON)相對(duì)容易,但您將付出損失時(shí)間的代價(jià)。
一些SQL數(shù)據(jù)庫現(xiàn)在能夠編碼和解碼更現(xiàn)代的數(shù)據(jù)格式(如JSON、XML、GraphQL或YAML)作為原生特性。但是在內(nèi)部,數(shù)據(jù)通常使用相同的舊表格模型進(jìn)行存儲(chǔ)和索引。
在這些格式之間轉(zhuǎn)換數(shù)據(jù)要花費(fèi)多少時(shí)間?用一種更現(xiàn)代的方式存儲(chǔ)數(shù)據(jù)不是更容易嗎?一些聰明的數(shù)據(jù)庫開發(fā)人員仍在繼續(xù)進(jìn)行實(shí)驗(yàn),但奇怪的是,他們經(jīng)常會(huì)使用某種SQL解析器。
封送(Marshaling)是一項(xiàng)耗費(fèi)大量時(shí)間的工作
數(shù)據(jù)庫可以在表中存儲(chǔ)數(shù)據(jù),但是需要程序員編寫處理對(duì)象的代碼。設(shè)計(jì)數(shù)據(jù)驅(qū)動(dòng)的應(yīng)用程序的大部分工作,似乎都是找出從數(shù)據(jù)庫中提取的數(shù)據(jù)并將其轉(zhuǎn)換為業(yè)務(wù)邏輯可以處理的對(duì)象的最佳方法。然后,必須通過將對(duì)象中的數(shù)據(jù)字段轉(zhuǎn)換為SQL upsert來解組數(shù)據(jù)。難道沒有一種方法可以讓數(shù)據(jù)保持一種隨時(shí)可用的格式嗎?
SQL并非實(shí)時(shí)的
最初的SQL數(shù)據(jù)庫是為批處理分析和交互模式而設(shè)計(jì)的。具有長處理管道的流數(shù)據(jù)模型是一個(gè)相對(duì)較新的想法,而且它并不完全匹配。
主要的SQL數(shù)據(jù)庫是在幾十年前設(shè)計(jì)的,當(dāng)時(shí)的模型設(shè)想數(shù)據(jù)庫可以獨(dú)立運(yùn)行,像某種Oracle一樣回答查詢。有時(shí)它們反應(yīng)迅速,有時(shí)則不然。這就是批處理的工作方式。
一些最新的應(yīng)用程序要求更好的實(shí)時(shí)性能——不僅僅是為了方便,而且因?yàn)閼?yīng)用程序需要它。在現(xiàn)代的流媒體世界里,缺乏實(shí)時(shí)功能是行不通的。
為這些市場設(shè)計(jì)的最新數(shù)據(jù)庫非常重視速度和響應(yīng)能力。它們不提供那種復(fù)雜的SQL查詢,以免造成延遲。
JOIN是一個(gè)令人頭疼的問題
關(guān)系數(shù)據(jù)庫的強(qiáng)大之處在于將數(shù)據(jù)分解成更小、更簡潔的表。不過,問題也隨之而來。
使用JOIN動(dòng)態(tài)地重新組裝數(shù)據(jù)通常是作業(yè)中計(jì)算成本最高的部分,因?yàn)閿?shù)據(jù)庫必須處理所有數(shù)據(jù)。當(dāng)數(shù)據(jù)開始超出RAM時(shí),問題就開始了。
對(duì)于學(xué)習(xí)SQL的人來說,JOIN可能會(huì)讓人十分困惑。弄清楚內(nèi)部JOIN和外部JOIN之間的區(qū)別僅僅是個(gè)開始。尋找將多個(gè)JOIN連接在一起的最佳方式更為困難。內(nèi)部優(yōu)化器可能會(huì)幫上忙,但是當(dāng)數(shù)據(jù)庫管理員要求一個(gè)特別復(fù)雜的組合時(shí),它們就無能為力了。
列(Column)是對(duì)空間的浪費(fèi)
“NoSQL”運(yùn)動(dòng)的一個(gè)偉大思想就是讓用戶從列中解脫出來。如果有人想向條目添加新值,他們可以選擇他們想要的任何標(biāo)記或名稱。不需要更新模式來添加新列。
SQL捍衛(wèi)者在該模型中只看到了混亂。他們喜歡表自帶的順序,不希望開發(fā)人員匆忙添加新字段。他們有一定的道理,但是添加新列可能非常昂貴和耗時(shí),特別是在大型表中。將新數(shù)據(jù)放在單獨(dú)的列中并使用JOIN對(duì)它們進(jìn)行匹配會(huì)增加更多的時(shí)間成本和復(fù)雜性。
優(yōu)化器并非始終有用
數(shù)據(jù)庫公司和研究人員已經(jīng)花費(fèi)了大量時(shí)間開發(fā)優(yōu)秀的優(yōu)化器,這些優(yōu)化器可以分解查詢并找到排序其操作的最佳方式。
收益可能是顯著的,但是優(yōu)化器所能做的是有限的。如果查詢需要一個(gè)特別大的或細(xì)致的響應(yīng),那么優(yōu)化器不能只是說,“你真的確定嗎?”它必須把答案集合起來,然后按照指令去做。
有些數(shù)據(jù)庫管理員只有在應(yīng)用程序開始擴(kuò)展時(shí)才意識(shí)到這一點(diǎn)。早期的優(yōu)化足以在開發(fā)期間處理測試數(shù)據(jù)集。但是在關(guān)鍵時(shí)刻,優(yōu)化器無法發(fā)揮更多的功能。
反范式化(Denormalization)將表視為垃圾
面對(duì)想要更快性能的用戶和不想為更大、更昂貴的硬件付費(fèi)的用戶,開發(fā)人員經(jīng)常處于兩難境地。一種常見的解決方案是對(duì)表進(jìn)行反范式化處理,這樣就不需要復(fù)雜的JOIN或跨表操作。
這并非一個(gè)糟糕的技術(shù)解決方案,而且它經(jīng)常獲勝,因?yàn)榇疟P空間已經(jīng)變得比處理能力便宜。但是反范式化也拋棄了SQL和關(guān)系數(shù)據(jù)庫理論中最精華的部分。當(dāng)數(shù)據(jù)庫變成一個(gè)長CSV文件時(shí),所有這些花哨的數(shù)據(jù)庫功能幾乎都消失了。
附加特性會(huì)破壞數(shù)據(jù)庫
多年來,開發(fā)人員一直在為SQL添加新特性,其中一些非常優(yōu)秀。但另一方面,有些新特性可能會(huì)導(dǎo)致性能問題。一些開發(fā)人員警告稱,“您應(yīng)該特別小心子查詢(Subqueries),因?yàn)樗鼈儠?huì)減慢所有操作的速度”。另一些人則表示,“選擇像公共表表達(dá)式、視圖或Windows這樣的子集會(huì)使代碼過于復(fù)雜”。
例如,窗口函數(shù)(Window function)的設(shè)計(jì)是為了通過加速計(jì)算結(jié)果(如平均值)來加快基本數(shù)據(jù)分析的速度。但是許多SQL用戶會(huì)發(fā)現(xiàn)并使用一些附加的特性。在大多數(shù)情況下,他們會(huì)嘗試新功能,只有當(dāng)他們的機(jī)器慢得像爬行一樣時(shí)才會(huì)注意到這些問題。然后他們會(huì)需要一些經(jīng)驗(yàn)豐富的數(shù)據(jù)庫管理員來解釋發(fā)生了什么以及如何修復(fù)它。
原文標(biāo)題:9 reasons SQL has got to go,作者:Peter Wayner