一般而言架構都是隨著需求而改動的,以需求為導向。現在關係型數據庫還是主流,也是我們系統中必不可少的一部分。
但是應對有些需求的時候,關係型數據庫往往就撐不住了,需要非關係型數據庫來補充它。關係型數據庫會有哪些問題呢?
關係型數據庫
行存儲結構
如關係型數據庫是行存儲結構,所以當你只想拿一行裡面的幾列時,從硬盤讀取到內存中的數據也會是整行的數據,當數據量很大的時候,IO就吃不消了。當然是可以通過垂直分表來解決這種情況,但是垂直分表也會帶來複雜性,具體不展開可以看我寫的這篇文章
還有例如頭條的關注列表,如果放在關係型數據庫中,那肯定就是你的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的練級攻略 的文章