NoSQL :一個帝國的崛起
01關系數據庫帝國
現在是公元2009年,關系帝國已經統治了我們30多年,實在是太久了。
1970年,科德提出關系模型,1974年張伯倫和博伊斯制造出了SQL ,帝國迅速建立起了統治。
從北美到歐洲, 從歐洲到亞洲, 無數程序員臣服在他的腳下。
帝國給我們提供了良好的福利:
簡單而強大的關系模型
靈活的SQL
還有我們非常喜歡的事務和ACID,把我們從底層并發的細節中解放出來。
使用這些福利,程序員們開發了無數的系統,每個系統的核心都是關系數據庫。
時代在不斷地變遷,編程語言的城頭不斷變換大王旗,但是存儲在表格中的數據,一直巋然不動。
數據永遠是一個企業最寶貴的資產。
但是帝國也給我們套上了沉重的枷鎖:模式和規范化。
帝國規定:必須事先定義好模式(表結構)才能保存數據!
所有的數據至少得滿足第一范式,甚至第二范式、第三范式、BCNF范式!
如果實現不了,就會被投進監獄,對于某些部落來講,即使是做一個簡單的冗余字段,都會被別人恥笑。
帝國宣稱的SQL移植性也欺騙了我們,SQL雖然被標準化,但是每個廠商DB2, Oracle, SQL Server都有自己的方言!
尤其是在計算日期和字符串操作。還有存儲過程,幾乎每個廠商都會自己搞一套,根本無法移植!
02危機
上世紀90年代,面向對象技術的流行給帝國帶來了一次嚴重的危機:
對象-關系的阻抗不匹配。
“對象(Object)”有繼承,子類,父類,關聯,聚合,多態;
而關系數據庫就是簡單的表格!
他們是如此的不同,簡直是水火不容,矛盾不可調和。
那個時候,帝國的東邊出現了一個叫面向對象數據庫OODB的部落, 號稱可以把Java對象,C#對象,Ruby對象等等都一股腦地、直接存儲到OODB當中去。
把對象直接保存到數據庫?這實在是一個美妙的特性。
但是OODB實在是不爭氣,很快偃旗息鼓,在幾個小領地茍延殘喘。
2001年,有個叫Gavin King的27歲小伙子,開發了一個叫做Hibernate 的東西,在對象和關系之間搭了一座橋,叫O/R Mapping。
這一下子贏得了Java 程序員的芳心。
Hibernate再接再勵,又推出了NHibernate, 打入了.NET的領地。
隨著iBatis, JPA等更多O/R Mapping工具和接口的出現,關系數據庫帝國成功地度過了這一次的危機。
后來有個好事者Martin Fowler,居然寫了一本書《企業應用架構模式》, 在里邊一本正經地把各種O/R Mapping的模式都總結了一遍:“單表繼承”,“類表繼承”,“活動記錄”。。。。。。
這一番騷操作又替關系數據庫帝國續命20年不止。
03新希望
沒過多久,互聯網大潮來了,歷史再次給了我們一個機會。
互聯網的用戶數如此之多,并發數如此之高, 讓我們始料未及。
數據量是如此巨大,數據種類如此豐富,更讓我們目瞪口呆。
文字、圖片、鏈接、日志、社交關系,大量的數據蜂擁而至,單臺機器上的數據庫很快就撐不住了。
帝國先是拼命擴容,恨不得把一臺機器弄成1024G的內存,1024T的硬盤,還美名其曰垂直擴展。
但是機器功能越強,價格就越貴,臣民們的稅負越來越重,很快就受不了了。
沒辦法,帝國只好做水平擴展,把數據分布在多臺機器上,這需要精心的規劃,還需要程序員和應用程序精確地記住每一份數據放在哪里。
更要命的是,這種辦法丟掉了帝國引以為傲的福利:事務和一致性
04反抗
我決定反抗這個龐大的帝國, 我偷偷地帶領著一幫志同道合的兄弟離開了,我們要新建一塊清新自由的領地。
我們仔細地研究了關系帝國的缺點,派出了幾只小分隊分頭出擊。
誓師出征之時,我們對這四只小分隊都提出了同樣的要求:支持分布式和集群!!!
第一支小分隊由redis擔任隊長,memcached 擔任副手,他們很快便取得了成功,因為他們打擊到了關系帝國最大的缺點:高并發下,數據庫IO非常緩慢。
redis和memcached 做了一個大膽的決定,拋棄了硬盤,選擇了比硬盤快幾萬倍的內存, 把數據以key-value的方式放入其中。
超快的速度讓程序員們非常喜歡,他們不僅把session,配置信息,購物車的數據放入其中。
后來干脆把他倆當成了緩存來使用。
第二支小分隊由Mongodb帶領,CouchDB輔佐,他們敏銳地瞄準了用關系數據表保存起來很別扭的數據。
訂單到訂單項和支付, 訂單項到產品是典型的一對多關系,意味著數據是樹狀結構,那為什么不直接用一個JSON文檔來表示呢?
- {
- "orderId":"1",
- "userId":"123",
- "lineItems":[
- {
- "productId":"1356",
- "qty":"1"
- },
- {
- "productId":"2375",
- "qty":"2"
- }
- ],
- "shippingAddress":{
- "type":"xxx",
- "address":"xxx"
- },
- "payment":{
- "type":"alipay",
- "time":"xxxx"
- }
- }
MongoDB還和JavaScript,Node.js勾勾搭搭,把瀏覽器發來的JSON數據直接存儲到MongoDB中,輕松又方便。
第三支小分隊的頭領是Neo4j, 這家伙非常擅長圖結構,對于社交網絡、推薦系統的數據,用它來表示非常合適。
第四支小分隊由HBase帶領, Cassandra殿后, 他們都是列式數據庫,百億行 * 百萬列的數據對于他倆來說稀松平常。
這個小分隊也獲得了巨大的成功,移動互聯網所產生的海量數據,如日志、聊天記錄,監控數據,物聯網的數據,結構化并不強,非常適合用HBase這種列式數據庫來存放。
05新的帝國
幾年以后,四支小分隊順利班師,都帶回了大批的程序員擁躉,因為適合的才是最好的。
一個新的、可以和關系數據庫抗衡的帝國悄然成型。
經過一番激烈討論,我們給帝國起了一個響亮的名稱:NoSQL。
意思是不要SQL!
但是,加入NoSQL帝國的程序員發現我們也有非常明顯的弱點:
缺乏模式(如表結構)、數據完整性約束很弱、對事務的支持很弱,甚至干脆沒有, 這引起了程序員的強烈不滿和抗議。
有不少人短暫嘗鮮NoSQL以后,又拋棄了我們,重回SQL的懷抱。
我們決定和關系數據庫帝國議和,告訴他們說NoSQL的意思是Not Only SQL, 我們兩大帝國應該取長補短,和平共處。
經歷了幾年戰火的關系數據帝國也看清楚了IT趨勢,欣然接受。
從此,數據庫進入了混合存儲的時代!