面試官:說說你對NoSQL的瞭解,為什麼要有NoSQL

yes的練級手冊發表於2019-04-21

面試官:說說你對NoSQL的瞭解,為什麼要有NoSQL
一般而言架構都是隨著需求而改動的,以需求為導向。現在關係型資料庫還是主流,也是我們系統中必不可少的一部分。

但是應對有些需求的時候,關係型資料庫往往就撐不住了,需要非關係型資料庫來補充它。關係型資料庫會有哪些問題呢?

關係型資料庫

行儲存結構

關係型資料庫是行儲存結構,所以當你只想拿一行裡面的幾列時,從硬碟讀取到記憶體中的資料也會是整行的資料,當資料量很大的時候,IO就吃不消了。當然是可以通過垂直分表來解決這種情況,但是垂直分表也會帶來複雜性,具體不展開可以看我寫的這篇文章mysql分庫分表

還有例如頭條的關注列表,如果放在關係型資料庫中,那肯定就是你的id,你關注的人的id,這樣一行資料儲存著,然後關注的人有10個就會有10條這樣的記錄,然後你檢視你關注的列表的時候,就需要從資料庫裡面查10行記錄,然後組裝起來返回給前端展示。

強結構

強結構的意思就是關係型資料庫的表結構有很強的約束,必須按照這麼個格式儲存,就不夠靈活。所以當有新需求需要加欄位的時候就需要修改表的結構,如果表的資料很多的話修改表的結構可能會長時間鎖表,而導致表的不可用。

沒記憶體型資料庫快

例如redis,人家在記憶體裡,我們們關係型資料庫比不上它的速度。

全文檢索能力弱

如果提供全文檢索,一般關係型資料庫只能like全表掃描,效能很差,雖然像mysql也有全文索引。但是我覺得術業有專攻。因為資料庫的這些廠商想擴張一下他們軟體的廣度,他們當然想自己軟體支援所有的需求,然後讓大家都來用它。如果效果真的這麼好的話,像elasticsearch還活的下去嘛。例如mongodb4要支援acid事務等等這類。

一個軟體基礎的設計就決定了它在一方面是優的,一方面是欠缺的。**一般而言想實現本來就不屬於它的領域的東西,要麼會犧牲效能,要麼會犧牲靈活性。**所以我如下講的是針對每個型別NoSQL的優勢點,也就是它們的最強點。

NoSQL (not only sql)

NoSQL其實就是關係型資料庫的補充,就目前而言我們是不可能離開關係型資料庫的,所以NoSQL就來彌補關係型資料庫在某些情況下的不足。這裡把常見的NoSQL分為4類:K-V類、文件型、列式儲存型、全文搜尋型

1、K-V類

全稱Key-Value,這應該是我們都熟悉就像Map一樣。代表資料庫就是redis,redis的value還分了很多結構,例如:list、set、sorted set、hash、string等。

它是儲存在記憶體中的,所以速度快常用來作為快取伺服器。 而且因為它的結構導致有些操作比關係型資料庫簡單

舉個例子例如List的[LPUSHX key value]操作,將一個值插入到已存在的列表頭部,列表是有序的,如果在關係型資料庫中得怎麼辦,插入一條資料,並且將控制位置的那個欄位例如叫index,設為1。那是不是還得修改本來的那些資料,把後面所有行的index值都加一,這樣才能控制有序,之後刪除哪條資料,還得維護修改index。操作是比較麻煩的。

但是它ACID事務只支援I和C也就是隔離性和一致性,不支援原子性和永續性。所以在一些對事務要求的情況下就不適合了。

2、文件型

這個型別它的結構沒有約束,可以儲存任意結構,因為是文件嘛。啥意思呢,就是例如關係型資料庫中規定這個表欄位就兩個,一個id,一個name。如果你想存個sex欄位你就得修改表結構。那文件型不用,因為文件型儲存的資料格式一般都是Json,Json裡面的欄位我任意填,無拘無束。

{
 "id":"1",
 "name":"aa"
}
複製程式碼

我塞下一條我這樣寫

{
 "id":"2",
 "name":"bb",
 "sex":"man"
}
複製程式碼

而且這種型別的資料庫容易存複雜的結構,因為Json是一種強大的描述語言,可以清楚的描述複雜的資料結構。如果複雜的資料結構放到關係型資料中那可能就得分很多表。例如我使用者基本資訊一個表、使用者愛好的電影一個表,使用者愛好的音樂一個表、使用者愛好的遊戲一個表,巴拉巴拉的,這些Json就能一次性搞定不需要分這麼多表。

代表的資料庫有MongoDB。3.2之前的版本不支援join操作,之後出了個lookup來實現join操作。4.0版本之前是不支援事務的,之後雖說支援事務,但是業界還是很少用它來保證事務的

3、列式儲存型

也就是按列來儲存資料,關係型是按行儲存。 按行儲存的好處是業務可以簡單的獲取一行也就是多個列的資料,因為按行儲存資料都是連續的,所以磁碟一次操作就讀取所有列的資料。

但是按列的話,因為列的儲存是不連續的,所以磁碟讀取效率比行低

按行儲存寫如果操作也是一行一起的,保證的所有列的資料要麼都成功寫入,要麼的失敗 。 如果是按列的話就有可能有些列成功,有些列失敗

但是在大資料統計的時候,一般就統計某一列或者某幾列的資料。如果這時候是按行儲存的話,那麼每次從磁碟讀取到記憶體時都會讀取整行資料導致IO過大和資源的浪費。

所以節省I/O就採用按列儲存,這樣每次只需要拿想要的列進行統計。

代表的資料庫是HBase,多用於離線的大資料分析和統計。為啥離線?上面說了寫的操作可能會有問題,並且整行讀的效率低,所以一般都是線上資料拷過來弄成列資料庫,專門使用者資料分析。

4、全文檢索型

這種型的資料庫主要是用在傳統關係型資料庫在全文檢索無力的情況下。因為搜尋的條件很多,例如找物件在網站搜,女+170+杭州+愛吃辣+愛健身+愛旅遊+28歲。來想想關係型資料庫得怎麼建這個索引。。。就是搜尋條件的排列組合太多了。所以關係型資料庫吃不消。這時候記得引入全文檢索型資料庫。

全文檢索引擎採用倒排索引,也就是每個單詞都是索引,建立單詞到文件的索引,這樣滿足你搜尋條件的當此的結果都會快速的顯示出來。

代表的有Elasticsearch,分散式文件儲存方式。使用方式就是我們從關聯式資料庫中匯出資料,轉換成Json格式然後將其輸入Elasticsearch中建立索引然後使用。

具體Elasticsearch的東西這裡不做深入分析,不然就跑題了。有需自己查詢相關資料。還有雖然Elasticsearch也是面向文件的,但是人家的重點在於全文檢索,所以就這樣分類。

總結

關係型資料庫和非關係型資料庫相輔相成,所以我們要根據各自的優缺點和需求進行相應的架構。 沒有最好只有最合適。


如果錯誤歡迎指正! 個人公眾號:yes的練級攻略

相關文章