在過去,我們只需要學(xué)習(xí)和使用一種數(shù)據(jù)庫技術(shù),就能做幾乎所有的數(shù)據(jù)庫應(yīng)用開發(fā)。因為成熟穩(wěn)定的關(guān)系數(shù)據(jù)庫產(chǎn)品并不是很多,而供你選擇的免費版本就更加少了,所以互聯(lián)網(wǎng)領(lǐng)域基本上都選擇了免費的MySQL數(shù)據(jù)庫。在高速發(fā)展的WEB2.0時代,我們發(fā)現(xiàn)關(guān)系數(shù)據(jù)庫在性能、擴展性、數(shù)據(jù)的快速備份和恢復(fù)、滿足需求的易用性上并不總是能很好的滿足我們的需要,我們越來越趨向于根據(jù)業(yè)務(wù)場景選擇合適的數(shù)據(jù)庫,以及進行多種數(shù)據(jù)庫的融合運用。幾年前的一篇文章《One Size Fits All - An Idea Whose Time Has Come and Gone》就已經(jīng)闡述了這個觀點。
當(dāng)我們在討論是否要使用NoSQL的時候,你還需要理解NoSQL也是分很多種類的,在NoSQL百花齊放的今天,NoSQL的正確選擇比選擇關(guān)系數(shù)據(jù)庫還具有挑戰(zhàn)性。雖然NoSQL的使用很簡單,但是選擇卻是個麻煩事,這也正是很多人在觀望的一個原因。
NoSQL僅僅是一個概念,NoSQL數(shù)據(jù)庫根據(jù)數(shù)據(jù)的存儲模型和特點分為很多種類。
類型 | 部分代表 | 特點 |
列存儲 | Hbase Cassandra Hypertable | 顧名思義,是按列存儲數(shù)據(jù)的。最大的特點是方便存儲結(jié)構(gòu)化和半結(jié)構(gòu)化數(shù)據(jù),方便做數(shù)據(jù)壓縮,對針對某一列或者某幾列的查詢有非常大的IO優(yōu)勢。 |
文檔存儲 | MongoDB CouchDB | 文檔存儲一般用類似json的格式存儲,存儲的內(nèi)容是文檔型的。這樣也就有有機會對某些字段建立索引,實現(xiàn)關(guān)系數(shù)據(jù)庫的某些功能。 |
key-value存儲 | Tokyo Cabinet / Tyrant Berkeley DB MemcacheDB Redis | 可以通過key快速查詢到其value。一般來說,存儲不管value的格式,照單全收。(Redis包含了其他功能) |
圖存儲 | Neo4J FlockDB | 圖形關(guān)系的最佳存儲。使用傳統(tǒng)關(guān)系數(shù)據(jù)庫來解決的話性能低下,而且設(shè)計使用不方便。 |
對象存儲 | db4o Versant | 通過類似面向?qū)ο笳Z言的語法操作數(shù)據(jù)庫,通過對象的方式存取數(shù)據(jù)。 |
xml數(shù)據(jù)庫 | Berkeley DB XML BaseX | 高效的存儲XML數(shù)據(jù),并支持XML的內(nèi)部查詢語法,比如XQuery,Xpath。 |
以上NoSQL數(shù)據(jù)庫類型的劃分并不是絕對,只是從存儲模型上來進行的大體劃分。它們之間沒有絕對的分界,也有交差的情況,比如Tokyo Cabinet / Tyrant的Table類型存儲,就可以理解為是文檔型存儲,Berkeley DB XML數(shù)據(jù)庫是基于Berkeley DB之上開發(fā)的。
雖然09年出現(xiàn)了比較激進的文章《關(guān)系數(shù)據(jù)庫已死》,但是我們心里都清楚,關(guān)系數(shù)據(jù)庫其實還活得好好的,你還不能不用關(guān)系數(shù)據(jù)庫。但是也說明了一個事實,關(guān)系數(shù)據(jù)庫在處理WEB2.0數(shù)據(jù)的時候,的確已經(jīng)出現(xiàn)了瓶頸。
那么我們到底是用NoSQL還是關(guān)系數(shù)據(jù)庫呢?我想我們沒有必要來進行一個絕對的回答。我們需要根據(jù)我們的應(yīng)用場景來決定我們到底用什么。
如果關(guān)系數(shù)據(jù)庫在你的應(yīng)用場景中,完全能夠很好的工作,而你又是非常善于使用和維護關(guān)系數(shù)據(jù)庫的,那么我覺得你完全沒有必要遷移到NoSQL上面,除非你是個喜歡折騰的人。如果你是在金融,電信等以數(shù)據(jù)為王的關(guān)鍵領(lǐng)域,目前使用的是Oracle數(shù)據(jù)庫來提供高可靠性的,除非遇到特別大的瓶頸,不然也別貿(mào)然嘗試NoSQL。
然而,在WEB2.0的網(wǎng)站中,關(guān)系數(shù)據(jù)庫大部分都出現(xiàn)了瓶頸。在磁盤IO、數(shù)據(jù)庫可擴展上都花費了開發(fā)人員相當(dāng)多的精力來優(yōu)化,比如做分表分庫(database sharding)、主從復(fù)制、異構(gòu)復(fù)制等等,然而,這些工作需要的技術(shù)能力越來越高,也越來越具有挑戰(zhàn)性。如果你正在經(jīng)歷這些場合,那么我覺得你應(yīng)該嘗試一下NoSQL了。
如此多類型的NoSQL,而每種類型的NoSQL又有很多,到底選擇什么類型的NoSQL來作為我們的存儲呢?這并不是一個很好回答的問題,影響我們選擇的因素有很多,而選擇也可能有多種,隨著業(yè)務(wù)場景,需求的變更可能選擇又會變化。我們常常需要根據(jù)如下情況考慮:
其實NoSQL數(shù)據(jù)庫僅僅是關(guān)系數(shù)據(jù)庫在某些方面(性能,擴展)的一個彌補,單從功能上講,NoSQL的幾乎所有的功能,在關(guān)系數(shù)據(jù)庫上都能夠滿足,所以選擇NoSQL的原因并不在功能上。
所以,我們一般會把NoSQL和關(guān)系數(shù)據(jù)庫進行結(jié)合使用,各取所長,需要使用關(guān)系特性的時候我們使用關(guān)系數(shù)據(jù)庫,需要使用NoSQL特性的時候我們使用NoSQL數(shù)據(jù)庫,各得其所。
舉個簡單的例子吧,比如用戶評論的存儲,評論大概有主鍵id、評論的對象aid、評論內(nèi)容content、用戶uid等字段。我們能確定的是評論內(nèi)容content肯定不會在數(shù)據(jù)庫中用where content=’’查詢,評論內(nèi)容也是一個大文本字段。那么我們可以把 主鍵id、評論對象aid、用戶id存儲在數(shù)據(jù)庫,評論內(nèi)容存儲在NoSQL,這樣數(shù)據(jù)庫就節(jié)省了存儲content占用的磁盤空間,從而節(jié)省大量IO,對content也更容易做Cache。
//從MySQL中查詢出評論主鍵id列表 commentIds=DB.query("SELECT id FROM comments where aid='評論對象id' LIMIT 0,20"); //根據(jù)主鍵id列表,從NoSQL取回評論實體數(shù)據(jù) CommentsList=NoSQL.get(commentIds);
在某些應(yīng)用場合,比如一些配置的關(guān)系鍵值映射存儲、用戶名和密碼的存儲、Session會話存儲等等,用NoSQL完全可以替代MySQL存儲。不但具有更高的性能,而且開發(fā)也更加方便。
MySQL+Memcached的架構(gòu)中,我們處處都要精心設(shè)計我們的緩存,包括過期時間的設(shè)計、緩存的實時性設(shè)計、緩存內(nèi)存大小評估、緩存命中率等等。
NoSQL數(shù)據(jù)庫一般都具有非常高的性能,在大多數(shù)場景下面,你不必再考慮在代碼層為NoSQL構(gòu)建一層Memcached緩存。NoSQL數(shù)據(jù)本身在Cache上已經(jīng)做了相當(dāng)多的優(yōu)化工作。
Memcached這類內(nèi)存緩存服務(wù)器緩存的數(shù)據(jù)大小受限于內(nèi)存大小,如果用NoSQL來代替Memcached來緩存數(shù)據(jù)庫的話,就可以不再受限于內(nèi)存大小。雖然可能有少量的磁盤IO讀寫,可能比Memcached慢一點,但是完全可以用來緩存數(shù)據(jù)庫的查詢操作。
由于NoSQL是一個比較新的東西,特別是我們選擇的NoSQL數(shù)據(jù)庫還不是非常成熟的產(chǎn)品,所以我們可能會遇到未知的風(fēng)險。為了得到NoSQL的好處,又要考慮規(guī)避風(fēng)險,魚與熊掌如何兼得?
現(xiàn)在業(yè)內(nèi)很多公司的做法就是數(shù)據(jù)的備份。在往NoSQL里面存儲數(shù)據(jù)的時候還會往MySQL里面存儲一份。NoSQL數(shù)據(jù)庫本身也需要進行備份(冷備和熱備)?;蛘呖梢钥紤]使用兩種NoSQL數(shù)據(jù)庫,出現(xiàn)問題后可以進行切換(避免出現(xiàn)digg使用Cassandra的悲?。?/p>
本文只是簡單的從MySQL和NoSQL的角度分析如何選擇,以及進行融合使用。其實在選擇NoSQL的時候,你可能還會碰到關(guān)于CAP原則,最終一致性,BASE思想的考慮。因為使用MySQL架構(gòu)的時候,你也會碰到上面的問題,所以這里沒有闡述。
關(guān)于作者
孫立,目前在鳳凰網(wǎng)負(fù)責(zé)底層組的研發(fā)工作。曾就職于搜狐和ku6。多年互聯(lián)網(wǎng)從業(yè)經(jīng)驗和程序開發(fā),對分布式搜索引擎的開發(fā),高并發(fā),大數(shù)據(jù)量網(wǎng)站系統(tǒng)架構(gòu)優(yōu)化,高可用性,可伸縮性,分布式系統(tǒng)緩存,數(shù)據(jù)庫分表分庫(sharding)等有豐富的經(jīng)驗,并且對運維監(jiān)控和自動化運維控制有經(jīng)驗。開源項目phplock,phpbuffer的作者。近期開發(fā)了一個NOSQL數(shù)據(jù)庫存儲INetDB,是NoSQL數(shù)據(jù)庫愛好者。他的新浪微博是:http://t.sina.com.cn/sunli1223