對不起,必須放棄SQL!

2023-12-14     51CTO

原標題:對不起,必須放棄SQL!

作者丨Peter Wayner

編譯丨Noe

儘管SQL很受歡迎,也很成功,但它又總是充斥著種種矛盾。

SQL可能笨拙又冗長,但開發人員又經常發現它往往是他們提取所需數據的最簡單直接的方法。當查詢寫入正確時,它可以快如閃電,當查詢出錯時,它就會慢如蝸牛。SQL明明已經經歷了幾十年發展,但新功能仍然在不斷增加。

不過這些悖論並不重要,因為市場已經表明:時至今日,即使出現了不少更新的、更強大的選擇,SQL還是許多人的首選。無論是小網站還是大公司,各地的開發人員都知道SQL。

SQL的表格模型占據主導地位,以至於許多非SQL項目最終都添加了SQL的接口,因為用戶需要它。這甚至適用於NoSQL運動,儘管NoSQL的發明初衷是為了擺脫舊的範式。但最終,似乎還是SQL贏了。

大家都知道,SQL有一定的局限性,但這並不足以讓人們徹底放棄它。開發人員可能永遠不會起身將所有數據從SQL中遷移出去。但是SQL的問題是真實的,足以給開發人員帶來壓力,有時候甚至需要對某些項目進行重新設計。

下面是我們希望放棄SQL的9個原因,儘管我們心知肚明我們可能做不到。

SQL讓事情變得更糟的9種方式:

  • 表格無法縮放
  • SQL不是JSON或XML原生的
  • 列集是一項耗費大量時間的工作
  • SQL不是實時的
  • JOINS是一個令人頭疼的問題
  • 列是對空間的浪費
  • 優化器只是有時有用
  • 非規範化將表視為垃圾
  • 附帶的想法會破壞你的資料庫

表格無法縮放

關係模型喜歡錶格,所以我們不斷構建它們。這對於小型乃至普通大小的資料庫來說都沒問題。但這個模型要是用在真正的大型資料庫上就會開始崩潰。

有些人試圖通過將新舊資料庫結合來解決這個問題,比如將分片集成到舊的開源資料庫中。添加層似乎可以使數據更易於管理,並提供無限的規模。但這些增加的層可能隱藏地雷。根據分片中存儲的數據量,SELECT或JOIN的處理時間可能會截然不同。

分片還迫使DBA考慮數據可能存儲在不同的機器上,甚至可能存儲在不同的地理位置上的可能性。缺乏經驗的管理員在開始跨表搜索時,如果沒有意識到數據存儲在不同的位置,可能會感到困惑。模型有時會從視圖中抽象出位置。

一些AWS機器配備了24tb的RAM。為什麼?因為一些資料庫用戶需要這麼多。他們在SQL資料庫中有這麼多數據,並且在一台機器上,在一塊RAM中運行得更好。

SQL不是JSON或xml原生的

SQL在語言界可能是一種常青樹,但它並不特別適合JSON、YAML和XML等較新的數據交換格式。所有這些都支持比SQL更分層、更靈活的格式。SQL資料庫的核心仍然停留在關係模型中,表無處不在。

市場會想方設法掩飾這種常見的抱怨。使用正確的粘合代碼添加不同的數據格式(如JSON)相對容易,但時間的損失不可避免,你要為此做好準備。

一些SQL資料庫現在能夠編碼和解碼更現代的數據格式,如JSON、XML、GraphQL或YAML作為本地特性。但是在內部,數據通常使用相同的舊錶格模型進行存儲和索引。

在這些格式之間轉換數據要花費多少時間?用一種更現代的方式存儲數據不是更容易嗎?一些聰明的資料庫開發人員繼續進行實驗,但奇怪的是,他們常常最終選擇使用某種 SQL 解析器。

編組是一項耗費大量時間的工作

資料庫可以在表中存儲數據,而程式設計師編寫處理對象的代碼。設計數據驅動的應用程式的大部分工作似乎都是找出從資料庫中提取數據並將其轉換為業務邏輯可以處理的對象的最佳方法。然後,必須通過將對象中的數據欄位轉換為SQL upsert(即「update+insert」,「存在則更新,不存在則插入」)來解組數據。難道沒有一種方法可以讓數據保持隨時可用的格式嗎?

SQL不是實時的

最初的SQL資料庫是為批處理分析和交互模式而設計的。具有長處理管道的流數據模型是一個相對較新的想法,它並不完全匹配。

主要的SQL資料庫是在幾十年前設計的,當時的模型設想資料庫可以獨立運行,而且可以像某種先知一樣回答查詢。有時他們反應迅速,有時則不然。這就是批處理的工作方式。

一些最新的應用程式要求更好的實時性能——不僅僅是為了方便,而且因為應用程式需要它。在現代的流媒體世界裡,像靜坐山間的大師那樣巋然不動是行不通的。

專為這些市場設計的最新資料庫非常重視速度和響應能力。它們不提供那種複雜的SQL查詢,因為這種查詢會讓一切都遲滯下來。

連接是一個令人頭疼的問題

關係數據庫的強大之處在於將數據分解成更小、更簡潔的表。煩惱也如影隨形。

使用join動態地重新組裝數據通常是作業中計算成本最高的部分,因為資料庫必須處理所有數據。當數據開始超出RAM的容量時,令人頭疼的事情就開始了。

對於學習SQL的人來說,連接可能會令人難以置信地困惑。弄清楚內部join和外部join之間的區別僅僅是個開始。尋找將多個join連接在一起的最佳方式會使情況變得更糟。內部優化器可能會幫上忙,但是當資料庫管理員要求一個特別複雜的組合時,它們就無能為力了。

列是對空間的浪費

NoSQL的一個偉大思想就是讓用戶從列中解脫出來。如果有人想向條目添加新值,他們可以選擇他們想要的任何標記或名稱。不需要更新模式來添加新列。

SQL的擁護者在該模型中只看到混亂。他們喜歡錶格自帶的順序,不希望開發人員即時添加新欄位。他們有一定的道理,但是添加新列可能非常昂貴和耗時,特別是在大型表格中。將新數據放在單獨的列中並使用join對它們進行匹配,無疑會耗費更多的時間,並增加複雜性。

優化器只是有時有用

資料庫公司和研究人員已經花費了大量時間來開發出色的優化器,這些優化器可以分解查詢並找到排序其操作的最佳方式。

收益可能是顯著的,但是優化器所能做的是有限的。如果查詢需要一個特別大或者特別繁複的響應,那麼優化器不能只是說,「你真的確定嗎?」它必須匯總答案,然後按照指令去做。

有些DBA只有在應用程式開始擴展時才知道這一點。早期的優化足以處理開發過程中的測試數據集。但在關鍵時刻,優化器無法從查詢中榨取更多的能量。

非規範化將表視為垃圾

開發人員經常發現自己陷入了兩難境地:一方面,想要更快的性能,另一方面精打細算,不想為更大、更昂貴的硬體付費。一種常見的解決方案是對表進行非規範化,這樣就不需要複雜的連接或跨表操作。所有的數據都在一個長矩形中。

這不是一個糟糕的技術解決方案,而且它通常會有實效,因為磁碟空間已經變得比處理能力便宜。但是非規範化也拋棄了SQL和關係數據庫理論中最聰明的部分。當資料庫變成一個長CSV文件時,所有這些花哨的資料庫功能幾乎都消失了。

附加功能會破壞你的資料庫

多年來,開發人員一直在為SQL添加新特性,其中一些功能非常酷。但不得不提的是,這些花哨的功能通常是附加的,可能會導致性能問題。

一些開發人員警告說,你應該特別小心子查詢,因為它們會減慢所有操作的速度。另一些人則表示,選擇像公共表表達式、視圖或窗口這樣的子集會使代碼過於複雜。代碼的創建者可以閱讀它,但是其他人在試圖保持SQL的所有層和代的清晰性時都感到頭痛。這就像在看諾蘭的電影,只不過是用代碼寫的。

有些附加功能已經妨礙了之前行之有效的做法。窗口函數的設計是為了通過加速計算結果(如平均值)來加快基本數據分析的速度。但是許多SQL用戶會發現並使用一些附加的特性。在大多數情況下,他們會嘗試新功能,然後當他們的機器慢如蝸牛時才會注意到有些問題。之後,他們會需要一些有經驗的DBA來解釋發生了什麼以及如何修復它。

文章來源: https://twgreatdaily.com/zh-sg/8b9b5aed296e5b11364eced8680c9ef6.html