SQL還是NoSQL?架構師必備選型技能

2023-10-17 12:01:35

很多時候我們都會有這樣的疑問。

如果這時候直接去看MySQL、Mongo、HBase、Redis等資料庫的用法、特點、區別,其實有點太著急了。

這時候,最好從「資料模型」開始討論。

1、SQL vs NoSQL

現在最著名的資料模型應該是SQL,它基於Edgar Codd在1970年提出的關係模型:

資料被組織成關係(relations),在SQL中稱為表(table),其中每個關係都是元組(tuples)的無序集合(在SQL中稱為行)。

那什麼是NoSQL?

現在很多非關係型資料庫會被稱為NoSQL,其含義往往被解釋 「Not only SQL」。

採用NoSQL的驅動因素在於:

  • 資料量。 比SQL更好的擴充套件性需求,包括支援超巨量資料集或超高寫入吞吐量
  • 查詢方式。 關係模型不能很好支援的一些特定查詢操作
  • 動態擴充套件。 對關係模式的一些限制表示沮喪,需要更加具有動態和表達力的資料模型

2、資料模型的差異

SQL 和 NoSQL資料庫的差異有很多,包括容錯性和並行處理,我們這裡暫時只討論資料模型的差異。

關係型模型的主要優勢在於:

  • 聯結操作
  • 多對一和多對多關係更簡潔的表達

注意,簡單的多對多適合關係型模型,複雜的多對多更適合圖模型

我們以檔案型NoSQL為例,它和SQL對比的核心優勢在於:

  • 模式靈活性
  • 區域性性帶來的效能優勢

2.1 模式靈活性

「模式靈活性」的特點,往往被稱為「schema-fress模式」,但是我們並不能將它直接理解為「無模式」。

因為我們在讀取資料時,往往存在某種資料結構的隱式轉換,所以我們稱之為「讀時模式」更準確(資料結構是隱式的,只有讀取時才解釋)。

而傳統關係型資料庫,對應可以稱之為「寫時模式」(模式是顯示的,並且在寫入資料庫時被約束必須遵守)。

這兩者差異跟程式語言中的動態檢查(執行時)和靜態檢查(編譯時)比較類似。

「模式靈活性」的優點在於:

  • 避免了大表變更時的停機或者耗時
  • 支援包含多種類似資料結構
  • 可以隨時改變資料結構

「模式靈活性」帶來的損害則是需要應用層做好結構約束,並且保證對歷史資料的相容性。
一般典型關係型場景,「模式靈活性」反而會導致難以維護。

2.2 區域性性的效能優勢

注意注意,區域性性優勢僅適用於需要同時存取檔案中大部分資料的場景。

如果我們的查詢需要存取整個檔案,那麼儲存區域性性具備顯著的效能優勢。

此時,如果資料被劃分到了多個表中,則需要存取多個表來檢索資料,會浪費更多的磁碟IO並花費更多的時間。

如果我們的存取只需要檔案中的一小部分資料,那麼對於大型檔案來說就是一種浪費。

3、資料模型分析原則

對於一份資料儲存,「資料模型」的建立, 就是考慮應該通過 SQL 還是 NoSQL 進行 資料組織 。

那麼,結合前面對SQL和NoSQL的介紹與對比,我們總結了以下幾個維度,來具體考慮如何建立「資料模型」。

3.1 資料物件關係

多對一或者多對多,一般考慮SQL。

一對多的關係,可以考慮SQL或者NoSQL。

3.2 查詢效能

如果我們的查詢通常需要存取整個檔案,那麼儲存區域性性具備顯著的效能優勢,關係型的join效能較差,因此可以考慮NoSQL。

(業務上,一般會通過整體結果快取,對關係型join查詢加速)

如果通常是區域性資料物件、獨立實體查詢,考慮SQL。

3.3 寫入吞吐量

如果需要超高的寫入吞吐量,考慮NoSQL。

3.4 擴充套件性

  • 屬性擴充套件:如果物件屬性不確定,且經常變動,NoSQL更靈活。
  • 超巨量資料集擴充套件:NoSQL通常更好。
  • 單value大小:單value如果過大,可能導致資料庫寫入失敗。考慮拆分物件,或者分級儲存到物件儲存。一般單value不要超過100KB(壓縮後)。

3.5 延遲選擇資料庫型別

資料模型分析主要是根據業務場景區分 關係型 還是 非關係型。

延遲考慮具體資料庫選型,用RDS還是Mongo還是其他資料庫,它們之間的功能性差異在逐漸變少。

具體選擇可以結合 研發人員熟悉程度、資料規模、其他非功能性需求 來判斷。

一些例子:

  • Mongo 4.x支援事務
  • MySQL 8.0支援JSON格式
  • DB-engine上,mysql和mongo都從本身定位逐步擴充套件為multi-model

 

 

參考:

《資料密集型應用系統設計》

 

都看到最後了,原創不易,點個關注,點個贊吧~
文章持續更新,可以微信搜尋「阿丸筆記 」第一時間閱讀,回覆【筆記】獲取Canal、MySQL、HBase、JAVA實戰筆記,回覆【資料】獲取一線大廠面試資料。
知識碎片重新梳理,構建Java知識圖譜:github.com/saigu/JavaK…(歷史文章查閱非常方便)