背景
一直受傳統RDB的影響,對於資料庫表的設計可能大多數開發人員都形成了思維定勢。在雲端運算和大資料背景下,RDBMS正在接近極限,KV儲存將受到越來越多的關注。學習NoSQL,不求能革RDBMS的命,但希望在設計思路上能得到一些拓寬,很多情境裡,SQL表的設計和計算語句其實蠻難受的。
RDBMS天生不是分布式的,因其保持著ACID的特性發展至今,非常重視資料完整性,但在機器規模增長的情況下,ACID是不可擴充的。同時,隨著資料量和訪問頻率增加,ACID所要維護的開銷在增大。分割資料庫,無論水平還是垂直,都是在分散總資料和讀取需求,達到最佳化目的,維護代價和難度也隨之上升。而KV的尋找本質是散列表,且資料量無論如何增大,尋找時間幾乎固定不變,即非常適合大規模資料。ACID很注重CAP中的C,而參考現實世界中很多事務,比如快遞,從你下單、付款到取貨,資金和物品的流轉並不嚴格一致,只要在一段時間內整個交易的最後結果滿足一致性就可以了。同樣,NoSQL和RDBMS比,更偏向於BASE(Basically Available, Soft-state, Eventually consistent)的折中,重視可用性,但不追求狀態的嚴密性,且滿足最終一致性。下面我以mongodb為例,展現一些他的特性和情境,期待NoSQL在當下能被更多的開發人員拿來一顯身手。
mongodb與RDBMS
mongodb是面向文檔的nosql,CouchDB則是這一類資料庫的元祖。從總體上看,
mongodb是最親和RDBMS的一個NoSQL,能解決大部分關係型資料庫解決的問題
跟面向列儲存的HBase相比,面向文檔儲存和面向行儲存更接近,比如在沒有索引的情況下,掃描整個表內記錄,同樣是掃描全文檔,及文檔的每個欄位
mongodb的索引同樣也是B樹,在一些索引的最佳化和設計上會和MySQL比較相似(當然需要遵循mongo的設計來做,不完全劃等號)
你可以把mongodb拿RDBMS一樣來使用(當然不推薦這麼做),無非是將一行記錄變成mongodb裡的json對,在document(相當於mysql的table)之間,也可以做類似外鍵一樣的引用
mongodb雖然沒有嚴格的事務性操作,但是開發人員自己可以做到類似事務的效果。這一點也算是mongodb貼近RDBMS的一個表現吧。
以下會從各個主要關注點來展開mongo的特性,展現角度更偏向於想要調研使用mongodb的人,看看mongodb是否符合自己的業務情境,也希望我的分析會有所協助。
儲存結構怎麼樣
Mongodb的儲存類似JSON,每個db內有多個collection,相當於table,每個collection內是許許多多的document,這個document的schemeless的。本質上,他的面向文檔指的是key-value中的value,而這個value可以是一個值(引用id或基本類型),可以是一個數組,也可以是一個文檔(嵌套的json對)。
一對多是最常遇到的情境,mysql中要使用兩張或以上表的關聯甚至join進行查詢,在mongo中直接使用嵌套型或引用型(用id)就可以了。沒有特殊需求的話,嵌套的方式只要一張"表"就可以實現。比如我這樣建立一個人的資訊:
{
id : 1,
name : "pelick",
hobbies : {
"GameA", "GameB", "GameC"
},
friends : {
male : {
2, 3, 4 # id refer to other person
},
female : {
{
name : "Rita",
hobbies : { "dancing" }
},
{
name : "Kaka",
nickname : "Riva"
}
}
}
}
上述這樣的結構中,展現了無模式、value為數組、嵌套、引用等。
處理好多對多的關係可謂是NoSQL的精髓所在。理論上,可以在一個集合中完成儲存。不過實際上這樣的情況非常罕見。這是由於查詢的多樣性所導致的,若是只有一種類型的查詢,則這種多對多的關係放在一個良好設計的集合中,雖然會有大量的冗餘,但是效率一定是最高的。如何設計這種資料庫的關鍵就是看你有多少種查詢,每一種的頻率是多少,使用的其他要求是什麼樣的。對於不同的查詢,同樣的資料庫設計的效能也是大不一樣。還有一點,一般不要拆成三個集合,這是傳統的關係型資料庫的思維方式。而常見的情況就是拆成兩個集合,然後有一部分冗餘,對最常用的查詢做一個索引。
總結就是兩張表,一張裡面存了另外一張裡的id集合,有冗餘存放,主要是根據查詢情境設計和建索引,不要和RDBMS一樣變三張。此外還有個好處是可以進行正反向查詢,在各自的欄位裡加上id數組。
接下來請看第2頁精彩內容:
推薦閱讀:
CentOS編譯安裝MongoDB
CentOS 編譯安裝 MongoDB與mongoDB的php擴充
CentOS 6 使用 yum 安裝MongoDB及伺服器端配置
Ubuntu 13.04下安裝MongoDB2.4.3
如何在MongoDB中建立新資料庫和集合
MongoDB入門必讀(概念與實戰並重)