常見的NoSQL方案

m0_60725291 2022-01-08 00:02:30 阅读数:153

nosql 方案


關系庫並不完美,存在一些缺點:

  • 關系數據庫存儲的是行記錄,無法存儲數據結構;
  • 關系數據庫的 schema 擴展很不方便;
  • 關系數據庫在大數據場景下 I/O 較高;
  • 關系數據庫的全文搜索功能比較弱;

針對上述問題,分別誕生了不同的 NoSQL 解决方案,這些方案與關系數據庫相比,在某些應用場景下錶現更好。

但世上沒有免費的午餐,NoSQL 方案帶來的優勢,本質上是犧牲 ACID 中的某個或者某幾個特性,應該將 NoSQL 作為 SQL 的一個有力補充。

常見的 NoSQL 方案分為 4 類:

  • K-V 存儲:解决關系數據庫無法存儲數據結構的問題,以 Redis 為代錶;
  • 文檔數據庫:解决關系數據庫强 schema 約束的問題,以 MongoDB 為代錶;
  • 列式數據庫:解决關系數據庫大數據場景下的 I/O 問題,以 HBase 為代錶;
  • 全文搜索引擎:解决關系數據庫的全文搜索性能問題,以 Elasticsearch 為代錶;

K-V 存儲

K-V 存儲的全稱是 Key-Value 存儲,其中 Key 是數據的標識,和關系數據庫中的主鍵含義一樣,Value 就是具體的數據。

Redis 是 K-V 存儲的典型代錶,它是一款開源(基於 BSD 許可)的高性能 K-V 緩存和存儲系統。Redis 的 Value 是具體的數據結構,包括 string、hash、list、set、sorted set、bitmap 和 hyperloglog,所以常常被稱為數據結構服務器。

Redis 的缺點主要體現在並不支持完整的 ACID 事務,Redis 雖然提供事務功能,但 Redis 的事務和關系數據庫的事務不可同日而語,Redis 的事務只能保證隔離性和一致性(I 和 C),無法保證原子性和持久性(A 和 D)。

雖然 Redis 並沒有嚴格遵循 ACID 原則,但實際上大部分業務也不需要嚴格遵循 ACID 原則。

文檔數據庫

為了解决關系數據庫 schema 帶來的問題,文檔數據庫應運而生。文檔數據庫最大的特點就是 no-schema,可以存儲和讀取任意的數據。目前絕大部分文檔數據庫存儲的數據格式是 JSON(或者 BSON),因為 JSON 數據是自描述的,無須在使用前定義字段,讀取一個 JSON 中不存在的字段也不會導致 SQL 那樣的語法錯誤。

文檔數據庫的 no-schema 特性,給業務開發帶來了幾個明顯的優勢:

  • 新增字段簡單;
  • 曆史數據較好的兼容,即使沒有新增的字段,也不會導致錯誤,只會返回空值,代碼進行兼容處理即可;
  • 可以很容易存儲複雜數據;

文檔數據庫的這個特點,特別適合電商和遊戲這類的業務場景。

文檔數據庫 no-schema 的特性帶來的這些優勢也是有代價的,最主要的代價就是事務支持上較麻煩,需要額外的編碼;
文檔數據庫另外一個缺點就是無法實現關系數據庫的 join 操作;

列式數據庫

關系數據庫按照行式來存儲數據,主要有以下幾個優勢:

  • 業務同時讀取多個列時效率高,因為這些列都是按行存儲在一起的,一次磁盤操作就能够把一行數據中的各個列都讀取到內存中。
  • 能够一次性完成對一行中的多個列的寫操作,保證了針對行數據寫操作的原子性和一致性;否則如果采用列存儲,可能會出現某次寫操作,有的列成功了,有的列失敗了,導致數據不一致。

行式存儲的優勢是在特定的業務場景下才能體現,如果不存在這樣的業務場景,那麼行式存儲的優勢也將不複存在,甚至成為劣勢,典型的場景就是海量數據進行統計。

例如,計算某個城市體重超重的人員數據,實際上只需要讀取每個人的體重這一列並進行統計即可,而行式存儲即使最終只使用一列,也會將所有行數據都讀取出來。如果單行用戶信息有 1KB,其中體重只有 4 個字節,行式存儲還是會將整行 1KB 數據全部讀取到內存中,這是明顯的浪費。而如果采用列式存儲,每個用戶只需要讀取 4 字節的體重數據即可,I/O 將大大减少。

除了節省 I/O,列式存儲還具備更高的存儲壓縮比,能够節省更多的存儲空間。普通的行式數據庫一般壓縮率在 3:1 到 5:1 左右,而列式數據庫的壓縮率一般在 8:1 到 30:1 左右,因為單個列的數據相似度相比行來說更高,能够達到更高的壓縮率。

同樣,如果場景發生變化,列式存儲的優勢又會變成劣勢。典型的場景是需要頻繁地更新多個列。因為列式存儲將不同列存儲在磁盤上不連續的空間,導致更新多個列時磁盤是隨機寫操作;而行式存儲時同一行多個列都存儲在連續的空間,一次磁盤寫操作就可以完成,列式存儲的隨機寫效率要遠遠低於行式存儲的寫效率。此外,列式存儲高壓縮率在更新場景下也會成為劣勢,因為更新時需要將存儲數據解壓後更新,然後再壓縮,最後寫入磁盤。

基於上述列式存儲的優缺點,一般將列式存儲應用在離線的大數據分析和統計場景中,因為這種場景主要是針對部分列單列進行操作,且數據寫入後就無須再更新删除。

全文搜索引擎

傳統的關系型數據庫通過索引來達到快速查詢的目的,但是在全文搜索的業務場景下,索引也無能為力,主要體現在:

  • 全文搜索的條件可以隨意排列組合,如果通過索引來滿足,則索引的數量會非常多。
  • 全文搜索的模糊匹配方式,索引無法滿足,只能用 like 查詢,而 like 查詢是整錶掃描,效率非常低。

全文搜索基本原理

全文搜索引擎的技術原理被稱為“倒排索引”(Inverted index),也常被稱為反向索引、置入檔案或反向檔案,是一種索引方法,其基本原理是建立單詞到文檔的索引。之所以被稱為“倒排”索引,是和“正排“索引相對的,“正排索引”的基本原理是建立文檔到單詞的索引。

全文搜索的使用方式

全文搜索引擎的索引對象是單詞和文檔,而關系數據庫的索引對象是鍵和行,兩者的術語差异很大,不能簡單地等同起來。因此,為了讓全文搜索引擎支持關系型數據的全文搜索,需要做一些轉換操作,即將關系型數據轉換為文檔數據。

目前常用的轉換方式是將關系型數據按照對象的形式轉換為 JSON 文檔,然後將 JSON 文檔輸入全文搜索引擎進行索引。

--------來源《極客課程》∙ 學習摘要

版权声明:本文为[m0_60725291]所创,转载请带上原文链接,感谢。 https://gsmany.com/2022/01/202201080002303123.html