【轉載】關聯式資料庫還是NoSQL資料庫

renjixinchina發表於2013-05-14
【轉載地址】

簡單的說明了為什麼要使用NoSQL。接下來我們看下如何把NoSQL引入到我們的專案中,我們到底要不要把NoSQL引入到專案中。

在過去,我們只需要學習和使用一種資料庫技術,就能做幾乎所有的資料庫應用開發。因為成熟穩定的關聯式資料庫產品並不是很多,而供你選擇的免費版本就更加少了,所以網際網路領域基本上都選擇了免費的MySQL資料庫。在高速發展的WEB2.0時代,我們發現關聯式資料庫在效能、擴充套件性、資料的快速備份和恢復、滿足需求的易用性上並不總是能很好的滿足我們的需要,我們越來越趨向於根據業務場景選擇合適的資料庫,以及進行多種資料庫的融合運用。幾年前的一篇文章《》就已經闡述了這個觀點。

當我們在討論是否要使用NoSQL的時候,你還需要理解NoSQL也是分很多種類的,在NoSQL百花齊放的今天,NoSQL的正確選擇比選擇關聯式資料庫還具有挑戰性。雖然NoSQL的使用很簡單,但是選擇卻是個麻煩事,這也正是很多人在觀望的一個原因。

NoSQL的分類

NoSQL僅僅是一個概念,NoSQL資料庫根據資料的儲存模型和特點分為很多種類。

型別

部分代表

特點

列儲存

Hbase

Cassandra

Hypertable

顧名思義,是按列儲存資料的。最大的特點是方便儲存結構化和半結構化資料,方便做資料壓縮,對針對某一列或者某幾列的查詢有非常大的IO優勢。

文件儲存

MongoDB

CouchDB

文件儲存一般用類似json的格式儲存,儲存的內容是文件型的。這樣也就有有機會對某些欄位建立索引,實現關聯式資料庫的某些功能。

key-value儲存

Tokyo Cabinet / Tyrant

Berkeley DB

MemcacheDB

Redis

可以透過key快速查詢到其value。一般來說,儲存不管value的格式,照單全收。(Redis包含了其他功能)

圖儲存

Neo4J

FlockDB

圖形關係的最佳儲存。使用傳統關聯式資料庫來解決的話效能低下,而且設計使用不方便。

物件儲存

db4o

Versant

透過類似面嚮物件語言的語法運算元據庫,透過物件的方式存取資料。

xml資料庫

Berkeley DB XML

BaseX

高效的儲存XML資料,並支援XML的內部查詢語法,比如XQuery,Xpath。

以上NoSQL資料庫型別的劃分並不是絕對,只是從儲存模型上來進行的大體劃分。它們之間沒有絕對的分界,也有交差的情況,比如Tokyo Cabinet / Tyrant的Table型別儲存,就可以理解為是文件型儲存,Berkeley DB XML資料庫是基於Berkeley DB之上開發的。

NoSQL還是關聯式資料庫

雖然09年出現了比較激進的文章《》,但是我們心裡都清楚,關聯式資料庫其實還活得好好的,你還不能不用關聯式資料庫。但是也說明了一個事實,關聯式資料庫在處理WEB2.0資料的時候,的確已經出現了瓶頸。

那麼我們到底是用NoSQL還是關聯式資料庫呢?我想我們沒有必要來進行一個絕對的回答。我們需要根據我們的應用場景來決定我們到底用什麼。

如果關聯式資料庫在你的應用場景中,完全能夠很好的工作,而你又是非常善於使用和維護關聯式資料庫的,那麼我覺得你完全沒有必要遷移到NoSQL上面,除非你是個喜歡折騰的人。如果你是在金融,電信等以資料為王的關鍵領域,目前使用的是Oracle資料庫來提供高可靠性的,除非遇到特別大的瓶頸,不然也別貿然嘗試NoSQL。

然而,在WEB2.0的網站中,關聯式資料庫大部分都出現了瓶頸。在磁碟IO、資料庫可擴充套件上都花費了開發人員相當多的精力來最佳化,比如做分表分庫(database sharding)、主從複製、異構複製等等,然而,這些工作需要的技術能力越來越高,也越來越具有挑戰性。如果你正在經歷這些場合,那麼我覺得你應該嘗試一下NoSQL了。

選擇合適的NoSQL

如此多型別的NoSQL,而每種型別的NoSQL又有很多,到底選擇什麼型別的NoSQL來作為我們的儲存呢?這並不是一個很好回答的問題,影響我們選擇的因素有很多,而選擇也可能有多種,隨著業務場景,需求的變更可能選擇又會變化。我們常常需要根據如下情況考慮:

  1. 資料結構特點。包括結構化、半結構化、欄位是否可能變更、是否有大文字欄位、資料欄位是否可能變化。
  2. 寫入特點。包括insert比例、update比例、是否經常更新資料的某一個小欄位、原子更新需求。
  3. 查詢特點。包括查詢的條件、查詢熱點的範圍。比如使用者資訊的查詢,可能就是隨機的,而新聞的查詢就是按照時間,越新的越頻繁。

NoSQL和關聯式資料庫結合

其實NoSQL資料庫僅僅是關聯式資料庫在某些方面(效能,擴充套件)的一個彌補,單從功能上講,NoSQL的幾乎所有的功能,在關聯式資料庫上都能夠滿足,所以選擇NoSQL的原因並不在功能上。

所以,我們一般會把NoSQL和關聯式資料庫進行結合使用,各取所長,需要使用關係特性的時候我們使用關聯式資料庫,需要使用NoSQL特性的時候我們使用NoSQL資料庫,各得其所。

舉個簡單的例子吧,比如使用者評論的儲存,評論大概有主鍵id、評論的物件aid、評論內容content、使用者uid等欄位。我們能確定的是評論內容content肯定不會在資料庫中用where content=’’查詢,評論內容也是一個大文字欄位。那麼我們可以把 主鍵id、評論物件aid、使用者id儲存在資料庫,評論內容儲存在NoSQL,這樣資料庫就節省了儲存content佔用的磁碟空間,從而節省大量IO,對content也更容易做Cache。

//從MySQL中查詢出評論主鍵id列表 
commentIds=DB.query("SELECT id FROM comments where aid='評論物件id' LIMIT 0,20"); 
//根據主鍵id列表,從NoSQL取回評論實體資料 
CommentsList=NoSQL.get(commentIds);

NoSQL代替MySQL

在某些應用場合,比如一些配置的關係鍵值對映儲存、使用者名稱和密碼的儲存、Session會話儲存等等,用NoSQL完全可以替代MySQL儲存。不但具有更高的效能,而且開發也更加方便。

NoSQL作為快取伺服器

MySQL+Memcached的架構中,我們處處都要精心設計我們的快取,包括過期時間的設計、快取的實時性設計、快取記憶體大小評估、快取命中率等等。

NoSQL資料庫一般都具有非常高的效能,在大多數場景下面,你不必再考慮在程式碼層為NoSQL構建一層Memcached快取。NoSQL資料本身在Cache上已經做了相當多的最佳化工作。

Memcached這類記憶體快取伺服器快取的資料大小受限於記憶體大小,如果用NoSQL來代替Memcached來快取資料庫的話,就可以不再受限於記憶體大小。雖然可能有少量的磁碟IO讀寫,可能比Memcached慢一點,但是完全可以用來快取資料庫的查詢操作。

規避風險

由於NoSQL是一個比較新的東西,特別是我們選擇的NoSQL資料庫還不是非常成熟的產品,所以我們可能會遇到未知的風險。為了得到NoSQL的好處,又要考慮規避風險,魚與熊掌如何兼得?

現在業內很多公司的做法就是資料的備份。在往NoSQL裡面儲存資料的時候還會往MySQL裡面儲存一份。NoSQL資料庫本身也需要進行備份(冷備和熱備)。或者可以考慮使用兩種NoSQL資料庫,出現問題後可以進行切換(避免出現digg使用Cassandra的悲劇)。

總結

本文只是簡單的從MySQL和NoSQL的角度分析如何選擇,以及進行融合使用。其實在選擇NoSQL的時候,你可能還會碰到關於CAP原則,最終一致性,BASE思想的考慮。因為使用MySQL架構的時候,你也會碰到上面的問題,所以這裡沒有闡述。

關於作者

孫立,目前在鳳凰網負責底層組的研發工作。曾就職於搜狐和ku6。多年網際網路從業經驗和程式開發,對分散式搜尋引擎的開發,高併發,大資料量網站系統架構最佳化,高可用性,可伸縮性,分散式系統快取,資料庫分表分庫(sharding)等有豐富的經驗,並且對運維監控和自動化運維控制有經驗。開源專案phplock,phpbuffer的作者。近期開發了一個NOSQL資料庫儲存INetDB,是NoSQL資料庫愛好者。他的新浪微博是:


感謝對本文的策劃及審校。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15747463/viewspace-761009/,如需轉載,請註明出處,否則將追究法律責任。

相關文章