面試官:說說你對NoSQL的瞭解,爲何要有NoSQL

通常而言架構都是隨着需求而改動的,以需求爲導向。如今關係型數據庫仍是主流,也是咱們系統中必不可少的一部分。

可是應對有些需求的時候,關係型數據庫每每就撐不住了,須要非關係型數據庫來補充它。關係型數據庫會有哪些問題呢?前端

關係型數據庫

行存儲結構

關係型數據庫是行存儲結構,因此當你只想拿一行裏面的幾列時,從硬盤讀取到內存中的數據也會是整行的數據,當數據量很大的時候,IO就吃不消了。固然是能夠經過垂直分表來解決這種狀況,可是垂直分表也會帶來複雜性,具體不展開能夠看我寫的這篇文章mysql分庫分表mysql

還有例如頭條的關注列表,若是放在關係型數據庫中,那確定就是你的id,你關注的人的id,這樣一行數據保存着,而後關注的人有10個就會有10條這樣的記錄,而後你查看你關注的列表的時候,就須要從數據庫裏面查10行記錄,而後組裝起來返回給前端展現。redis

強結構

強結構的意思就是關係型數據庫的表結構有很強的約束,必須按照這麼個格式存儲,就不夠靈活。因此當有新需求須要加字段的時候就須要修改表的結構,若是表的數據不少的話修改表的結構可能會長時間鎖表,而致使表的不可用。sql

沒內存型數據庫快

例如redis,人家在內存裏,我們關係型數據庫比不上它的速度。mongodb

全文檢索能力弱

若是提供全文檢索,通常關係型數據庫只能like全表掃描,性能不好,雖然像mysql也有全文索引。可是我以爲術業有專攻。由於數據庫的這些廠商想擴張一下他們軟件的廣度,他們固然想本身軟件支持全部的需求,而後讓你們都來用它。若是效果然的這麼好的話,像elasticsearch還活的下去嘛。例如mongodb4要支持acid事務等等這類。數據庫

一個軟件基礎的設計就決定了它在一方面是優的,一方面是欠缺的。**通常而言想實現原本就不屬於它的領域的東西,要麼會犧牲性能,要麼會犧牲靈活性。**因此我以下講的是針對每一個類型NoSQL的優點點,也就是它們的最強點。緩存

NoSQL (not only sql)

NoSQL其實就是關係型數據庫的補充,就目前而言咱們是不可能離開關係型數據庫的,因此NoSQL就來彌補關係型數據庫在某些狀況下的不足。這裏把常見的NoSQL分爲4類:K-V類、文檔型、列式存儲型、全文搜索型bash

一、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也就是隔離性和一致性,不支持原子性和持久性。因此在一些對事務要求的狀況下就不適合了。

二、文檔型

這個類型它的結構沒有約束,能夠存儲任意結構,由於是文檔嘛。啥意思呢,就是例如關係型數據庫中規定這個表字段就兩個,一個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版本以前是不支持事務的,以後雖然說支持事務,可是業界仍是不多用它來保證事務的

三、列式存儲型

也就是按列來存儲數據,關係型是按行存儲。 按行存儲的好處是業務能夠簡單的獲取一行也就是多個列的數據,由於按行存儲數據都是連續的,因此磁盤一次操做就讀取全部列的數據。

可是按列的話,由於列的存儲是不連續的,因此磁盤讀取效率比行低

按行存儲寫若是操做也是一行一塊兒的,保證的全部列的數據要麼都成功寫入,要麼的失敗 。 若是是按列的話就有可能有些列成功,有些列失敗

可是在大數據統計的時候,通常就統計某一列或者某幾列的數據。若是這時候是按行存儲的話,那麼每次從磁盤讀取到內存時都會讀取整行數據致使IO過大和資源的浪費。

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

表明的數據庫是HBase,多用於離線的大數據分析和統計。爲啥離線?上面說了寫的操做可能會有問題,而且整行讀的效率低,因此通常都是線上數據拷過來弄成列數據庫,專門用戶數據分析。

四、全文檢索型

這種型的數據庫主要是用在傳統關係型數據庫在全文檢索無力的狀況下。由於搜索的條件不少,例如找對象在網站搜,女+170+杭州+愛吃辣+愛健身+愛旅遊+28歲。來想一想關係型數據庫得怎麼建這個索引。。。就是搜索條件的排列組合太多了。因此關係型數據庫吃不消。這時候記得引入全文檢索型數據庫。

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

表明的有Elasticsearch,分佈式文檔存儲方式。使用方式就是咱們從關係數據庫中導出數據,轉換成Json格式而後將其輸入Elasticsearch中創建索引而後使用。

具體Elasticsearch的東西這裏不作深刻分析,否則就跑題了。有需本身查找相關資料。還有雖然Elasticsearch也是面向文檔的,可是人家的重點在於全文檢索,因此就這樣分類。

總結

關係型數據庫和非關係型數據庫相輔相成,因此咱們要根據各自的優缺點和需求進行相應的架構。 沒有最好只有最合適。


若是錯誤歡迎指正! 我的公衆號:yes的練級攻略

相關文章
相關標籤/搜索