現今雲計算的從業人員對NoSQL一詞并不感到陌生,雖然很多技術人員都長期從事關系資料庫的工作,但現在他們對NoSQL技術充滿期待。對于企業來說,從關系型資料庫到NoSQL資料庫轉變絕對是個需要深思熟慮的大改變。這涉及的不僅是軟體的變化,更多的是對于資料存儲上觀念性的變化。
CouchDB專家兼作者Bradley Holt認為NoSQL并不是反SQL的運動,為對應的工作選擇最恰當的工具才是正确的模式。
大多數非關系資料庫都具有快速和可伸縮的特性。通過放棄關系存儲模型和架構,關系資料庫便可脫離由緊密結合的架構所帶來對其施加的限制。應用程式也無需再連結資料庫内表中的資料。
MongoDB和CouchDB以及RavenDB(RavenDB是基于Mocrosoft .NET Framework編寫的)等文檔資料庫除了某些特定的轉換外,通常都是通過HTTP為其提供資料,然後将資料存儲為JSON(JavaScript Object Notation)格式的文檔,并提供多種語言的API接口。這三款開源的文檔資料庫都将簡潔、速度和可伸縮性作為其設計的重要名額。RavenDB的建立者Ayende Rahien就表示“RavenDB的設計初衷就旨在快速寫入并讀取”。
NoSQL——關系資料庫的有力補充
現今,NoSQL和文檔資料庫成為關系資料庫的有力補充(而非替代品),同時提供了更多的選擇。如果企業準備将資料遷移,那麼選擇NoSQL的重要标準就是要看CAP(Consistency、Availability和Partition Tolerance),也就是我們所說的一緻性、可用性和分區容忍性。但CAP原則要求在分布式系統隻能選擇一緻性、可用性和分區容忍性其中的兩項。是以如果企業認為一緻性是重要的那麼關系資料庫理應是優先選擇的對象。
例如在銀行等應用領域,一緻性是非常重要的,這要求必須随時考慮每個資料塊。而CAP原則中的可用性也不容忽視,某些領域的資料可用性要比等待所有交易資料收集齊全更為重要。最後在水準縮放時,分區容忍性對于文檔資料庫顯得尤為關鍵。但MongoDB并不支援複雜的事務,隻支援少量的原子操作,是以不适用于“轉帳”等對事務和一緻性要求很高的場合。這就要求需要一個關系資料庫來對交易進行過進階别的控制。
文檔資料庫的關鍵特性
RESTful HTTP API
RESTful API設計就是為了消除建立松散耦合服務時的依賴關系,這也正是過去分布式體系結構的缺陷。雖然要映射到一些協定需要依賴于中繼資料的可用性以及方法等,但REST API的設計目标就是不依賴于任何通信協定。
衆多NoSQL資料庫都可通過RESTful的方式通路。這樣可以通過URI的方式建立資料庫連接配接,而查詢和指令則通過HTTP實作。MongoDB和CouchDB都提供了特定語言的API接口,以便編寫和執行查詢、更新。但MongoDB的預設設定仍然是使用TCP與資料庫進行連接配接。而RavenDB則具備基于.NET的用戶端API,可簡化與資料庫的互動過程。
單個記錄中的相關資料
大多數人都錯誤的認為非關系資料庫是一種包含沒有相對關系結構的記錄的檔案。而文檔資料庫中存儲的資料包含形狀資料——具有節點的樹。資料庫中的每個記錄都是以文檔形式存在的。并具備自我描述的功能,而不依賴于任何其他文檔。
示例代碼1:文檔資料庫(MongoDB)中的典型事例
{
"name" : "Jim",
"scores" : [ 75, 99, 87.2 ]
}
示例代碼2 CouchDB示例
"Subject": "I like Plankton"
"Author": "Rusty"
"PostedDate": "5/23/2006"
"Tags": ["plankton", "baseball", "decisions"]
"Body": "I decided today that I don't like baseball. I like plankton."
示例代碼3 包含字元串資料、數字和數組的簡單結構。還可在對象内嵌入對象,以獲得更複雜的文檔結構。
"BlogPostTitle”: “LINQ Queries and RavenDB”,
"Date":"\/Date(1266953391687+0200)\/",
"Content":”Querying RavenDB is very familiar for .NET developers who are already
using LINQ for other purposes”,
"Comments":[
{
"CommentorName":"Julie",
"Date":"\/Date(1266952919510+0200)\/",
"Text":"Thanks for using something I already know how to
work with!",
"UserId":"users/203907"
},
]
唯一鍵
所有資料庫都需要鍵。如果不提供鍵系統則會自動在内部建立一個鍵。鍵對于資料庫的索引功能至關重要。自身域中要求有已知鍵,在上面的示例代碼中存在對“users/203907”的引用。這正式RavenDB利用鍵值并允許使用者定義文檔間關系的方式。
以JSON格式存儲資料
共同點都是使用JSON存儲器資料。事實上,CouchDB和RavenDB(以及其他許多資料庫)均采用JSON格式存儲資料。MongoDB對JSON使用稱之為“二進制JSON”(BSON)的轉換,以便能夠執行二進制序列化。BSON是資料的内部表現形式,從程式設計的角度看開發者不會發現有任何差別。
JSON的簡潔性使其很容易将幾乎所有語言的對象結構轉換為JSON。 是以,開發者可在應用程式中定義對象,然後将其直接存儲在資料庫中。這使得開發人員不需要使用對象關系映射程式 (ORM) 不斷在資料庫架構和類/對象架構之間進行轉換。
MongoDB BSON API的資料類型和約定清單添加了一種資料類型及其他一些資料類型,以便充實JSON中的可用内容。而在一個單元中存儲和檢索相關資料可提供顯著的性能和可伸縮性的優勢。資料庫不必四處查找常用的相關的資料,因為資料都存儲在相同的位置。
類型的集合
與資料庫互動時,應用程式如何知道哪一項代表學生,哪一項代表書,以及哪一項代表部落格文章? 資料庫使用集合這一概念解決了這一問題。 對于與特定集合(如學生集合)關聯的任何文檔(無論其架構如何)都可在從該集合請求資料時對其進行檢索。使用字段來訓示類型也十分常見。這隻是使搜尋過程更加輕松,但哪些内容應進入集合,哪些不應進入集合,由開發者的應用程式決定。
架構靈活的資料庫
前面介紹的“示例代碼1”包含自己的架構。 每個記錄負責自己的架構,甚至負責單個資料庫或集合中包含的架構。并且一個學生記錄并不需要與另一學生記錄相比對。開發者隻需利用此靈活性來提高效率。例如,為什麼存儲 null 值? 您可以在屬性(如“most_repeated class”)不具有值時執行以下操作:
"name" : "Jim",
"scores" : [ 75, 99, 87.2 ]
"name" : "Julie",
"scores" : [ 50, 40, 65 ],
"most_repeated_class" : "Time Management 101"
文檔資料庫和領域驅動開發
規劃域類(可能成為資料庫中的文檔)時,開發者可查找通常最為獨立的資料(例如具有其明細項的訂單),并将其作為單個資料結構加以關注。在訂購系統中,可能還有客戶和産品。但或許會在不需要訂單的客戶資訊的情況下通路該訂單,并且可能會在不需要通路使用産品的訂單的情況下使用該産品。這意味着,盡管會發現許多機會來包含獨立資料結構(如具有其明細項的訂單),但這并不表示在某些情形下可以不必或者不通過外鍵聯接資料。
每個資料庫都提供各種可用模式的指南,并為使用者指明使用哪些模式可以獲得最大成功。 例如MongoDB文檔讨論稱為“上級數組”的模式,它可加快在聯接文檔時對相關資料的通路速度。
在關系資料庫中,重複資料是個錯誤。 對資料庫進行标準化可確定不出現此情況。 使用NoSQL資料庫(尤其是分發資料庫)時,對資料進行逆規範化是必要且可接受的。
查詢和更新
每個資料庫都附帶用于查詢和更新的API。盡管它們可能不是核心API的一部分,但多語言API是通過附加元件提供的。其他查詢依賴預定義的視圖和稱為Map/Reduce的模式。此過程的映射階段使用這些視圖,并且各個資料庫的映射職責是不同的。映射還使資料庫能夠跨多個處理器分發查詢處理。化簡階段可擷取映射查詢(如果已分發,則為多個查詢)的結果,并将資料聚合到要傳回到用戶端的結果中。
盡管CouchDB要求開發者通過預定義的Map/Reduce視圖進行查詢,但MongoDB(也使用視圖和Map/Reduce)另外提供執行臨時查詢的功能。RavenDB允許使用預定義索引進行查詢,但也支援臨時查詢,并将根據開發者的實際運作時查詢自動為其建立索引。但在大多數時候,當不采用SQL資料庫的已知架構和關系本質時,開發者會丢失的一個功能是執行臨時查詢的功能。通過嚴格控制查詢,文檔資料庫能夠實作其快速性能。
資料庫變革
有許多非關系資料庫都不屬于NoSQL範疇。但既然這扇門已經敞開,就會鼓舞更多人去探索其可用的功能,并考慮如何改進它。
本文轉自 wws5201985 51CTO部落格,原文連結:http://blog.51cto.com/wws5201985/792418,如需轉載請自行聯系原作者