為什麼新的分散式資料庫又開始支持關係模型了?
hbase/bigtable這樣的資料庫,比關係資料庫多了一層,表達能力其實強於關係模型啊,輔以索引和良好設計的查詢語言,應該比RDBMS要好用才對
為什麼Google F1和TiDB又開始支持關係模型了
我理解題主覺得 BigTable 系的 NoSQL 並不是表達力高於關係模型,而是靈活性吧?
比如彙編語言和高級語言,哪個表達力更強,哪個靈活度更高應該很明顯。SQL 的表達力是毋庸置疑,都(差不多?)是圖靈完備的語言了,你說強不強,用 KV 的 API 寫個正確的多表 JOIN 試試?。。。。而且最關鍵是,這個是事實標準啊。。。多少程序員是寫完 hello world 以後,就開始學 SQL 的。另外,我們發現關係模型其實是可以和分散式很好結合的,並非水火不容,而且關係模型本身並沒有限定實現方式,只不過過去的 RDBMS 都是在單機上實現,很多 Pattern 並沒有在分散式場景中有 good practice,特別是 OLTP, 所以大家可能就會覺得這個沒法做。其實還是能的,就是比較複雜,不過我相信我們團隊能 handle 這個複雜度。
另外很重要的一個就是輪子哥說到的事務,其實隔離級別和跨行事務是個好東西,能用更少的代碼寫出正確的程序,這個交給程序員寫基本就呵呵了,只不過在分散式場景下需要犧牲點什麼。本身 MVCC 並不是太難做,其實犧牲掉的是一定的延遲(分散式事務基本只有一種搞法:2PC)....不過呢,一旦想開了,這也不是什麼大事,反正 Multi-Paxos 或者 Raft 這樣的複製協議總是要有延遲的,2PC 帶來的 contention cost 相比複製其實也不算太多。而且延遲問題也可以通過緩存和靈活降低隔離級別等方法搞定。
一
旗幟鮮明地先說結論:之所以新的分散式資料庫又開始支持關係模型了,是因為大部分程序員的資料庫水平太糟糕。二
論證之前慣例先吐個小槽。咱們就不吐槽題主的問題描述本身是不是就已經論證了我的觀點,比如啥「良好的查詢語言」是不是等於SQL等於關係模型,又比如「比關係資料庫多了一層」是什麼奇怪的說話。我還是來講兩個真實的小故事吧。大概4、5年前,大家還在老老實實地用RDBMS實現業務資料庫,一段時間過去發現查詢變得很慢,大家紛紛議論:要不要換成NoSQL啊?
然後我被派去做幫助做資料庫優化,然後加了幾個索引,把查詢的時間從30多秒優化到了30多毫秒。大概4、5個月前,大家已經開始快快樂樂地在新業務的資料庫上用上NoSQL了,結果發現查詢也開始變得很慢,大家紛紛議論:要不要用文檔資料庫來加個索引啊?
然後我又被派來做NoSQL優化了,改了些partition key,重新定義了一些row key,拆了幾個entity,然後查詢時間從20多秒變成了20多毫秒。三要回答為什麼新的分散式資料庫又開始支持關係模型了,需要先搞明白兩件事情:
- 資料庫解決了什麼問題
- 關係模型解決了什麼問題
資料庫說得複雜特別複雜,但說得簡單,它就解決了兩個問題:數據怎麼存放和數據怎麼查詢。
而且這兩個問題互相關聯。舉個程序員都能明白的例子:如果你把數據存成了數組,那搜索查詢就只能是O(n)的效率了,如果你存成了二叉樹,那麼查詢效率就變成了O(logn)。業務查詢可不像搜索一個key值這麼簡單,常常複雜得要死,本來查詢就很難寫了,現在還得考慮數據物理存放方式來決定怎麼執行查詢更高效,這不是要逼死人嘛?所以早期的資料庫開發人員苦啊,什麼層級資料庫、網狀資料庫寫完查詢都得自己定義access path啊。然後就有了關係模型。
關係模型徹底改變了資料庫程序員的生活:不用管數據怎麼存了,你只要用SQL寫好查詢,然後查詢優化器會幫你把面向業務的查詢邏輯轉換成可以高效在數據的物理結構上執行的物理查詢。這簡直就像一下從彙編時代跨越到了高級語言的時代啊。早期的資料庫還需要大家自己思考怎麼建索引,相當於告訴查詢優化器哪些列是在查詢中有用,後來資料庫已經可以自動提示你該加什麼索引了,大部分程序員終於可以歡樂地徹底扔掉資料庫存儲引擎的知識了。
當然仍然有一小挫掌握了超能力的人,是可以手寫執行計劃,用Plan Guide強制執行的,他們說:查詢優化器是什麼?可以吃嗎?若干年後他們拯救了世界也打開了黑暗的大門(大誤...
四
好日子一直持續到資料庫負載大到不得不開始走向分布為止。分散式最大的問題是網路延遲問題,而網路延遲是物理問題,沒這麼容易解決。跨機事務做不了啊,查詢優化器再牛逼也優化不了跨網路的join啊。但業務還是得做啊,於是解決方案只有一個了:回到手工根據查詢來決定數據物理分布(這樣可以最大程度上避免跨網路的join),手工決定查詢的物理執行計劃,手工保證事務性的老路。
既然都已經全手工了,那還要原來的RDBMS幹嘛,於是NoSQL產品誕生了。搭配一些會手寫執行計劃手寫事務的超能力者使用,戰鬥力簡直有105這麼高。
大家很快就忘記了NoSQL其實是一個對現實妥協的產物,只有搭配一些精通數據存儲引擎知識的人才能用好。推廣開來之後,廣大吃瓜群眾表示NoSQL一點也不好用啊,自己要管的東西太多啦,我怎麼知道要怎麼設計數據的物理分布啊,瞎設計一下查詢起來就效率感人了啊,最終一致又是一個什麼鬼啦,想像一下討論怎麼嚴格保證一個「改動了3個entity且有不少if-else分支的方法」的最終一致性,感覺結論必然只有「呵呵」啊。
於是為了讓廣大吃瓜群眾用得開心,NoSQL的開發者不得不又開始走上了關係模型的老路。
五
題外話:你要問我這是不是一件好事,我當然覺得這是一件好事。什麼東西都先解決了有沒有,再解決好不好,分散式資料庫的發展也一樣。就像原來寫程序要懂體系結構,後來寫程序只要懂指針,再後來寫程序連指針也不需要了。寫資料庫應用,卻不需要很好的資料庫水平,這其實對大部分人來說都是一件值得開心的事情。為了能實現這一點,當然需要做資料庫的同學們多加努力了。題目中的關係模型的表現主要是指支持sql。應用開發人員用sql只需要告訴資料庫要什麼,不用去管怎麼做,開發效率高了很多。在支持事物的nosql上實現一個join,維護一下索引,累死人。而且關鍵是即使作為應用開發人員對查詢優化都懂+_+沒有計算能力的存儲節點上有些優化手段也用不上。
補充。其實數據類型系統對sql 的用戶非常重要,而實現起來非常麻煩,誰做誰知道。多數nosql 只支持整型,二進位串等原始類型。我們通常所說的「關係資料庫管理系統」是指具備以下兩個核心功能的系統:
- 以SQL作為數據定義/操作語言的關係型數據管理;
- 數據的訪問和操作符合事務語義。
前者是數據模型的抽象。關係模型是在應用中數據建模的便利性和系統實現和性能優化之間(長期以來被認為能夠達到合理平衡)的折中。在建模便利性/靈活性上,它不如OO建模;在性能優化實現上,它可能不如被深度定製/優化的很多系統。但在上世紀70年代末,關於關係資料庫是否能達到層次/網狀數據模型資料庫的性能的爭論,以及上世紀80年代末/90年代初,關於是否應該實現完全的面向對象數據模型的資料庫管理系統的爭論,這兩場爭論過後,我們現在看到的關係模型加上一些面向對象特性的數據模型抽象就基本成型了。Michael Stonebraker把這種系統叫做ORDBMS [1]。PostgreSQL是ORDBMS的代表。
後者是數據操作的抽象。事務一致性有不同級別 [2],ANSI/ISO SQL對隔離級別有定義,不同廠商的系統的實現不同,有的還實現了其他隔離級別。
無論是關係模型還是事務,都可以通過SQL來定義和操作。所以,很多時候SQL就被當作關係資料庫管理系統的代名詞。
BigTable/HBase剛出現時,既沒有關係模型支持(甚至都沒有數據模型支持)也沒有事務實現。所以後來這批系統(還有Cassandra,甚至包括Hadoop/MapReduce等)被稱為NoSQL,就是「沒有SQL的數據管理系統」。說它們「比關係資料庫多了一層」是不合適的。
當然,NoSQL系統優點鮮明:容錯,可伸縮(可部署在多個節點的集群上,題中所謂「分散式」),編程方便,社區活躍,版本迭代快,成功故事多...... 然後Michael Stonebraker和David DeWitt一起寫了2篇文章,發在Vertica當時的博客Database Column上,原帖已經被刪,網頁快照見[3]和[4]。在[3]的評論里,Joe Hellerstein (UCBerkeley教授)說:
-------------------------------
As a wise philosopher once said, Be a lover, not a fighter!Technically, I agree with much of this article, especially the history lesson on parallel data processing. ... (細節省略)
But none of that matters. It"s all about hearts and minds, and if the DB industry adopts the attitude in this article, it"s back to what I said at HPTS back in 2001: We Lose. See especially slides 5-10.
-------------------------------其中他提到的HPTS 2001報告[5]中有一句:
-------------------------------
Eventually they?ll come crying to us (結合上下文,they指OS folk,we指DB folk)– When they realize they should have had data independence– And we give ?em the best server platform-------------------------------簡單的講,他的觀點是:數據模型/事務等資料庫概念/技術的學習曲線長,上手慢,雖然數學性質漂亮,系統實現高效,但不是大多數程序員的首選。但是隨著應用越來越複雜,越來越多,越來越大,最終,資料庫技術是有用的,資料庫研究者應儘早介入這一過程...
問題中提到的現象其實就是這一過程的再現。當然要支持關係模型和事務,需要解決理論上CAP定理的限制問題,需要解決工程實現上的分散式並發控制代價問題。於是八仙過海,H-Store/VoltDB做數據分區+內存並發控制,Google Spanner/F1用原子鐘,Alibaba OceanBase用基線數據和更新數據分離。其實各人在做的是在應用/數據抽象和系統實現/優化中間尋找新的平衡。 M. Stonebraker說了,關係資料庫是OldSQL,HBase那一撥是NoSQL,現在大家在做的叫NewSQL[6]。
有意思的是,資料庫技術的發展中經歷了多次爭論/競爭,上面提到了三次,M. Stonebraker在三場爭論里都是主角。
- Michael Stonebraker, Dorothy Moore: Object-Relational DBMSs: The Next Great Wave. Morgan Kaufmann 1996, ISBN 1-55860-397-2
- Gerhard Weikum, Gottfried Vossen: Transactional Information Systems: Theory, Algorithms, and the Practice of Concurrency Control and Recovery. Morgan Kaufmann 2002, ISBN 1-55860-508-8
- http://web.archive.org/web/20090609124109/http://www.databasecolumn.com/2008/01/mapreduce-a-major-step-back.html
- http://web.archive.org/web/20090528063620/http://www.databasecolumn.com/2008/01/mapreduce-continued.html
- http://db.cs.berkeley.edu/jmh/talks/hpts2001-we-lose.pdf
- https://www.usenix.org/legacy/events/lisa11/tech/slides/stonebraker.pdf
這個問題很有意思,要分析好這個問題,可能要從過去的歷史談起。把時間往前推十多年,在2005年左右,我們可以看到在互聯網領域, 面對爆炸性增長的數據和請求量,以及互聯網公司低IT成本的訴求,傳統的關係型資料庫逐漸力不從心了。總的來說,有兩個主要的問題,一個是缺乏好的橫向擴展能力,一個處理單個請求的延時高。為什麼有這兩個問題? 要回答好這個問題,我們需要把時間再往前推幾十年,看看關係型資料庫,是怎麼變成2005年那個樣子的。
眾所周知,關係型的資料庫,首先是跟網狀/層次模型的資料庫幹了一仗,才奠定其江湖地位的。最終的結果是關係型資料庫成為結構化數據存儲的標配,而其他類型的資料庫則逐漸消失。為什麼能夠取勝的原因,@Vince Zhang 和 @錢衛寧 在回答中講了不少,下面我想結合自己的一些想法,提出一個 「資料庫三角」 的模型,來闡述下。
如大家所知, 生活中經常有三個要求只能滿足兩個的情況。分散式系統領域有CAP理論(cap三者只能滿足兩者),經濟學領域有蒙代爾三角(本國貨幣政策的獨立性,匯率的穩定性,資本的完全流動性不能同時實現,最多只能同時滿足兩個目標)。而資料庫領域,我們可以這樣定義一個資料庫三角:
對業務的支持度: 即資料庫產品的功能,能夠對業務開發起到多大的支持。資料庫產品功能越強大,那麼業務開發就越方便,對業務的支持度就越好。
工程實現複雜度:研發一款資料庫產品的難度。複雜度越高,則產品研發越不可行,尤其是對於數據存儲類產品而言,一個bug可能導致災難性的影響。
硬體要求: 資料庫產品對硬體的要求。要求越低,則產品的適用範圍越廣。
關係型資料庫之所以能夠興起並占統治地位,根本原因還在於它在:業務的支持度 - 工程實現複雜度 - 硬體要求 這三個點之間,做到了很好的平衡。從RDBMS開始出現的80年代,到2000左右互聯網爆發的前夜,絕大部分業務並沒有海量數據存儲的要求,也沒有海量請求的壓力,為此,基於單機開發一款能夠支持關係演算的資料庫產品, 也並沒有那麼難。而關係演算,則是當時銀行、財務等傳統IT界,業務系統開發的利器,而SQL更是直接基於財務場景發明出來的一門語言。
同時, 磁碟技術的不斷的發展,導致容量不斷增大,性能也在提高,硬體的紅利可以在資料庫產品內部架構大體不變的情況下, 支撐住業務的發展。
即使有一些大項目會碰到容量或者性能瓶頸問題,但這些大項目,比如銀行、電信等系統,往往是不缺錢的主,有大量IT預算,可以通過scale-up來解決問題。
這應該就是關係型資料庫,在傳統IT領域能夠通吃幾十年的主要原因。
但所有這些,都是建立在單機的基礎的。2000年後,互聯網呼嘯而來,先是在2C業務上,建立了絕對的優勢,進而又侵入傳統行業的地盤。最後大家發現,可能每家公司,每個業務都需要接入互聯網了,不然可能無法生存。而這對IT系統的開發,則是一個重大的挑戰。
挑戰首先出現在率先觸網的互聯網公司,比如BAT等。他們發現,單機資料庫的解決方案,無論如何也支撐不了海量的數據和訪問壓力了,而互聯網公司單用戶收入也有限,無法上昂貴的設備去做scale-up。
好在這些互聯網公司的業務特點是雖然數據量大,但是業務不複雜,庫表結構往往很簡單,寫操作和查詢也不複雜,有時候就是簡單的k-v插入和查詢。於是出現了分庫分表、NoSQL方案,進而衍生出無數的中間件和內存資料庫產品。在這些個「傳統」的互聯網公司的項目里,資料庫三角的格局,和NoSQL等產品的位置,是這樣的:
_______________________________________________________________________________
下面開始進入正題。
咱們這個問題是:「分散式資料庫為什麼又開始支持關係模型了?」 有了上面的背景和理論,我們再來看這個問題,就很簡單了。理由如下:
1. 分散式資料庫的需求,率先是由互聯網公司碰到的,這些公司用傳統的關係型資料庫做業務很痛苦, 不得不自造輪子。而由於自身的業務並不複雜,所以重點在解決分散式的問題(通過分散式技術降低硬體要求),而不用考慮複雜計算的問題(即支持sql或者100%兼容SQL標準語法)。BigTable、HBase、Redis等,無一不是這種情況。
2. 欠下的債總是要還的,互聯網在跑馬圈地之後,逐漸侵入傳統領域,這時候發現沒有關係演算,或者說沒有SQL這種描述能力強悍的語言不行,業務開發會很麻煩;還有比如需要事務的支持。正如輪子哥所說的:「關係是用來保持事務和並發的正確性的,顯然大家又重新意識到,這種事情讓程序員寫C++來保證是多麼的不靠譜。」
3. 於是不得不回到更大的範圍來考慮資料庫的問題,所以從才出現了各種NewSQL,比如OceanBase,TiDB等。
5. 當然還有一種產品,其發展路線是這樣的:
這條路是否能夠打到一個很好的結果,覆蓋廣泛的客戶,目前也是未盡可知。一個好的消息是,UDDB公測兩周來,已經有十幾個客戶來自不同行業的客戶,創建並開始測試UDDB,對於我們來說,是一個好的開始。
黃仁宇先生評價中國近代史,有句話說的很好:「中國的革命,好像一個長隧道,須要101年才可以通過。我們的生命縱長也難過99歲」。對於資料庫的發展而言,我們目前也正在處於這樣的一個隧道中。每個有志於做分散式資料庫的團隊,都在隧道里摸索,彷彿看到光亮但又有無盡彷徨。UCloud – 專業雲計算服務商
回答這個問題前得先搞清什麼叫關係型資料庫以及它和SQL的關係。簡單說關係型資料庫之所以叫關係型(Relation)是因為其建立在關係代數之上,Relation在數學中有明確的定義:
既然已經上升到數學,那麼某種意義上已經回答了該問題。也就是說不管你建立什麼樣的資料庫模型,最終都會落在關係代數上。而SQL就是一門關係代數語言。換種說法:支持SQL是目前所有資料庫終極的目標,即關係資料庫還是理論的制高點。以前寫過一篇博客,是關於資料庫模型的演變已經最終的關係型資料庫統治:http://darkhouse.com.cn/blog/2同時還有另一篇博客是關於NOSQL資料庫的,在知乎也有相應的回答,參考:https://www.zhihu.com/question/20304711/answer/101662227現將將原文黏貼如下:給定n個集合S1、S2、 S3、 ...、 Sn, R是一個n元數組(n-tuples),它的第一個元素取自集合S1,第二個元素取自集合S2,以此類推。我們將R稱之為基於該n 個集合的一個Relation,Sj為R的第j個域(Domain)。
關係型資料庫的統治
介紹大多數的軟體開發離不開資料庫,如果你把軟體定義為「程序」和「數據」,如何存儲數據一直是軟體開發過程中最值得去思考的問題。上世紀 80年代來,關係型資料庫已經讓大家從這個複雜的問題中解放了出來。至少對一部分開發者來說,他們再也不用愁數據存儲這個問題了, 以至那些企業應用軟體的用戶已經完全忽視了數據存儲。他們更熱衷於繪製業務流程圖以及對UI界面的指手畫腳, 數據存儲在他們的印象中就如同EXCEL中的幾個SHEET那樣理所當然。然而,理所當然的事物往往是最重要,也是最難實現的。 黑屋認為業務邏輯和UI是一堆沒有價值的「管道代碼」,因此應儘可能實現自動生成。
在另一個陣營中,一群人一直在挖掘數據存儲的潛力,他們造就了屬於這個時代的新名詞:「大數據」, 「Hadoop」, 「NoSQL」, 等等。他們更接近IT的本質(開發實質的信息處理軟體而非管道軟體),憑藉紮實的技術和進取心,撼動著強大的關係型資料庫。 然而這些IT新名詞僅僅是一段時期內的流行辭彙,還是能真正帶來一些變革?無論怎樣,它們確實影響到了如今的應用開發者。 「數據存儲」這個問題被重新提出來:突然多了那麼多資料庫,到底選擇哪個?看待這個問題不能只從技術層面上, 因為追隨新銳事物總能給人以先進的感覺,從而獲得超出實際的評價。
因此我們也不能僅僅將對比不同資料庫的特性來作為挑選的依據(而且這樣的文章已經夠多了)。如果我們重新回顧一下資料庫發展的歷史, 了解各個階段它要解決的問題,熟悉更多關於資料庫本質的內容,這將有助於我們做出正確的選擇。黑屋冀希望以此能讓企業應用軟體領域的用戶重新重視數據存儲; 也希望那些年輕的互聯網從業者更多的關注數據處理軟體的前塵往事,去創造更令人激動的未來。
本系列以資料庫發展歷史為主線,分別以5篇博客依次介紹:「關係型資料庫的統治」,「OLAP浪潮」,「列式資料庫的逆襲」,「互聯網時代的百家爭鳴」, 以及最後「MDB的多租戶數據模型」。
本文是這個系列的第一篇,首先介紹一些早期的資料庫模型,然後重點介紹關係型模型以及關係型資料庫。 雖然主題是資料庫模型,但如果不涉及底層的物理模型(物理介質上的數據結構),是很難描述全面的,同時為了避免過於技術, 對數據物理模型的描述只會點到為止。最後討論一些關係模型之後出現的數據模型,主要以實體-關係模型為主。
早期的資料庫模型我們在討論資料庫模型的時候是不能不提承載它的物理設備的,雖然資料庫模型從一開始就想擺脫硬體對它的限制,做到所謂的硬體獨立, 但一旦放諸於實際應用,你就必須得考慮硬體的實際承載能力。事實上,在計算機發展過程中,硬體和軟體總是相輔相成的: 硬體是軟體運行的容器,容器的形狀和大小決定了軟體的設計;然而軟體反映的是人類的思維,思維不受限制, 因此軟體就能反過來促使硬體按照它的定義去發展。早期的資料庫模型正是在磁碟被廣泛應用的基礎上發展起來的。
相對於磁帶的順序訪問(Sequential Access),磁碟提供的直接訪問(Random Direct Access)為軟體提供了更多的思維空間。 我們現在熟悉的文件系統也是在磁碟的基礎上實現的,思考一下,這種我們習以為常的文件夾包含文件夾和文件的層級架構是如何實現的? 這是個非常有趣的話題,但不在本文的討論範圍內。然而我們接下來要談的第一個資料庫模型和文件系統有著非常類似的層級結構, 它的名字就叫層級數據模型。
層級數據模型是以樹形結構組織數據的,要求每個子節點只能擁有唯一的父節點,從這個意義上它和現在的文件系統是一樣的。 然而作為一個資料庫系統,和文件系統最大的不同在於它要有能力對現實中的事物模型化。我們對現實世界中的事物往往存有一個概念上的抽象, 例如,公司內部的組織結構在我們的概念中就是一個層級,你能圖像化不同的部門、人、以及他們的上下級關係。 這種概念上的抽象需要進一步抽象到邏輯層面,即去除那些無關緊要的部分(比如剛從你腦中一閃而過的各種圖像),以便我們能把精力集中在問題本身。 經過上述思維過程後,我們便能畫出類似圖1中的層級數據模型。
文件系統和資料庫系統到底有什麼區別?從本質上它們是一樣的,文件系統是模擬了文件夾和文件的資料庫,資料庫是更細節化的文件系統。 有趣的是來自這兩個陣營的開發者至今還在相互對峙中。
圖1. 層級數據模型
接下來的問題是如何在計算機系統中實現這樣一個層級模型,這就是計算機軟體(或者說資料庫)所要負責的事情,即將數據邏輯模型和數據物理模型對應起來。 要了解這種對應關係是如何實現,我們有必要先簡單描述一下磁碟的工作原理。
磁碟顧名思義是一個表面帶磁性的圓形碟片,它能繞著中心軸快速的旋轉;磁碟表面的各個同心圓被稱為磁軌,二進位數據就是分散保存在這些磁軌上; 磁頭和磁臂負責定位處於特定磁軌中的特定扇區。為了簡化,假設我們的磁碟只有一個磁軌,這個磁軌被分為12個扇區,分別標上從0到11的編號(參見圖2)。
圖2. 單磁軌磁碟我們的單道磁碟如果以每分鐘10,000轉的速度旋轉(RPM),那麼通過簡單的換算,便得出磁頭從指向扇區6到指向扇區0所需的時間為3ms。 扇區0中正好保存著圖1層級結構中的根節點,即所有的「集團」信息。假設每個扇區的大小是512 Byte,每個「集團」信息需要100 Byte的長度, 那麼在扇區0中可以保存5個「集團」,分別是「集團1」到「集團5」(參見圖3)。如果我要看「集團1」的信息,那麼只需截取前100 Byte長的數據, 這裡面就包含了如「集團名字」等固有屬性信息,它們佔據88 Byte長;在剩下的12 Byte中,分別保存了3個指向子節點的指針,每個指針4 Byte長, 它們分別指向保存「公司1」、「公司2」、「公司3」的扇區;「公司2」對應的扇區10保存了「公司2」的屬性信息及其部門子節點所在的扇區編號, 這裡「財務部」和「IT部」的數據被分別保存在扇區4和扇區5。這樣通過層級間的導航,我們可以快速遍歷整個層級結構。 粗略估算一下,在不考慮緩存的情況下,獲取集團1下面公司2的IT部門信息大概需要9ms(按導航指引,訪問扇區0、10、5), 不算太慢,是不是?
圖3. 導航型資料庫這種通過數據記錄之間的直接指引並提供引導式訪問路徑的資料庫被稱為導航型資料庫(Navigational Database)。 考慮到上世紀60年代中期,磁碟速度還遠沒有現在那麼快的情況下,以這種物理模型實現的資料庫還是能提供可接受的性能的。 我們也看到,將層級數據模型對應到這種導航型的物理數據模型是比較直接的,沒有涉及複雜的數據結構和轉換, 這恰恰能說明這個時期的資料庫模型受限於硬體能力。
導航型資料庫的工作方式和現在導航軟體很類似:向前1000米,右轉,向前500米,左轉,向前100米,到達。
雖然現實世界中有許多事物本身就是以層級組織的,例如, 除了組織結構外,製造行業中的物料清單(BOM)也是個天然的層級結構, 然而層級結構並是一個通用數據模型。 還是以一個企業的組織結構為例,如果這個集團下面的所有公司共享一個財務部和IT部(這在現代企業架構中很常見), 那麼我們就得到如圖4這樣的網狀模型。與層級數據模型不同,網狀數據模型允許子節點有多個父節點,這樣便能實現「多對多」的實體對應關係。
圖4. 網狀數據模型網狀數據模型還是可以輕鬆的用導航型資料庫實現,這並不會添加太多的難度,只要在子節點上存有指向其各個父節點的指針即可。 然而無論是層級數據模型還是網狀數據模型,其訪問數據的路徑總是被嚴格限制的,你只能基於它給出的路徑,一個節點一個節點的去遍歷。 分別有2個著名的資料庫採用這兩種數據模型:其一是GE於1964年發布的Integrated Data Store(IDS),它是個網狀資料庫; 其二是IBM於1968發布的Management Information System(MIS),它是個層級資料庫。值得注意的是,MIS至今仍然被廣泛應用於銀行和電信領域。
還有一個最常見的層級資料庫就是WINDOWS系統中的註冊表,它被用於保存WINDOWS應用程序的配置信息。
雖然這兩種數據模型都將被隨之而來的關係型模型取代,但是它們代表了資料庫的原型,並一直影響著以後的資料庫實現。 即便是今天,我們依然能從這些早期的設計和實現中獲取無窮無盡的靈感。如今流行的NoSQL資料庫也多少讓人覺得是在「反祖」中獲得的新生。 在談論那些形形色色的互聯網資料庫之前,我們還是需要先花點時間來了解關係型數據模型。
關係型數據模型資料庫模型的歷史雖然不是起源於關係型模型,但必須得說關係型資料庫曾統一了所有的資料庫模型,並一直統治至今。 關係型模型進入人們視野的具體時間是E.F.Codd在1970年發表的論文: "A Relational Model of Data for Large Data Bank"。
很多人對關係型數據模型的印象是表和欄位,並還能想到的是表與表之間通過某些欄位可以關聯起來。似乎正因為這樣,關係型資料庫才被冠於這個名字。 然而關係型數據模型中的「關係」在英文中對應的單詞「Relation」是一個抽象的數學概念,它既不是獨指2個表之間的關係,也不等價於一個二維表(雖然習慣於以二維表來表示)。 數學中關於Relation的定義是這樣的:給定n個集合S1、S2、 S3、 ...、 Sn, R是一個n元數組(n-tuples),它的第一個元素取自集合S1,第二個元素取自集合S2,以此類推。我們將R稱之為基於該n 個集合的一個Relation,Sj為R的第j個域(Domain)。
換種方式表述:R是集合S1×S2×S3× ...×Sn笛卡爾積的一個子集。
很難將上述的定義與現在的關係型資料庫聯繫起來,然而這正是Codd在1970年那篇論文中的精華, 十年後,Larry Ellison也正是根據這篇論文開發了ORACLE資料庫。 Relation完全是個邏輯層面上的概念,將一個邏輯數據模型變成一個資料庫產品,需要在工程方面付出巨大的努力,並最終得到市場認可。 我們必然好奇是什麼樣的內在因素使關係型模型能得到工程師和市場的一致認可,即Codd當時引入關係型模型是要解決什麼問題?
需要解決的問題自然是層級數據模型和網狀數據模型的不足,即數據對底層物理存儲結構還是有很強的依賴性。 從前面對這兩個模型的描述中我們發現,在處理實體間關係這個問題上,它們都是以磁碟的扇區號為直接指向,這當然可以說是為了保證性能, 但在實際應用過程中,會帶來諸多不便。例如,你只能被限制在有限的幾條訪問路徑上,更大的問題還在於對模型的調整很有可能會同時牽涉磁碟重組和應用程序重寫。 Codd指出了當時資料庫系統中需要消除的三大數據依賴。
- 排序依賴:數據總是以一定的順序保存在磁碟上,例如以「集團號」從小到大的順序存儲, 應用程序如果只能按存儲順序處理數據,那麼哪天突然要求按另一種順序排列(如「集團名字」),它很有可能會運行失敗。 這就要求資料庫系統能將數據的存儲順序和展現順序獨立開。
- 索引依賴:索引被用來加快對數據的查詢和遍歷操作,但同時它會降低數據的插入性能。單從信息角度看,索引是個冗餘部件, 因此即使在沒有索引的情況下,應用程序應該也能正確運行(只是帶來性能的影響)。資料庫系統應該要保證,無論是添加還是刪除索引, 都不會導致應用程序的調整,即消除其對索引的依賴。
- 訪問路徑依賴:層級和網狀資料庫系統的訪問路徑都是一開始設計好的,應用程序只能被限制在這些規定好的訪問路徑上。 例如:如果想取得「部門」信息,那隻能根據預設好的路徑先通過「集團」,再到「公司」,最後找到所要的信息;反過來, 如果想根據「部門」信息找到對應的「集團」信息,那麼就先得建立「部門」的索引,然後設置從「部門」到「公司」最後到「集團」的導航指引。 這些訪問路徑都必須在一開始設計資料庫的時候考慮到,並生成對應的訪問程序,如果後期對數據模型有調整或者增加新的訪問路徑, 都意味著資料庫和應用程序的雙重調整。因此資料庫系統要有能力提供所有可能的訪問路徑,消除對訪問路徑的依賴。
如果你整理過個人電腦中的文件夾,你會經歷同樣的煩惱:你可以將文件按你所經歷過的項目來組織,也可以按文件對應於你專業的知識框架來組織, 討厭的是你只能選擇其中一種文件夾結構;如果你突然哪天想按年份層級來查閱文件,你會發現系統根本無法做到。
基於當時資料庫系統以上三點的不足,Codd進一步總結出,將來的資料庫系統要能做到「對稱探索」(Symmetric Exploitation), 即用戶可以根據任何已知的屬性組合去探索剩下的未知屬性。我們有理由相信關係型模型的靈感來源於數學,而正因為數學包羅萬象, 所以有能力去實現各種語義級別的數據探索。從Relation的數學定義中可以看出它屬於集合,那麼對於集合的所有操作包括: 交集、並集、子集等應可用於Relation。Codd在此基礎上提出了「關係代數」(Relation Algebra),其中的一些操作, 如:Projection, Join, Restriction為後來SQL語言的形成提供了理論基礎。
這裡的「探索」包含查詢、更新、插入和刪除等操作;對稱性不是體現在性能上,而是在訪問路徑上。
很明顯,Codd當時提出的關係型模型只是一種理論框架,它最大的成就在於賦予資料庫系統一個科學內核。 即定義了資料庫系統應該能而且必須要做到的事情,因為只有這樣它才能如同物理學一樣,與數學契合;才能成為一種真正的信息科學技術。 那麼接下來,留給工程師們的就是這麼一個遠大而又宏偉的目標——如何在計算機系統中實現或者接近這個模型。問題是憑藉當時的計算機性能, 要實現關係型數據模型是件非常具有挑戰的事情。然而正是其科學內核賦予它強大的吸引力,使得在以後的十年里,雨後春筍般誕生了許多號稱關係型資料庫的產品。
關係型資料庫開發關係型資料庫的難點在哪裡?我們先從「對稱探索」說起,要實現這個特徵,你必須要對一個Relation提供所有可能的訪問路徑。 例如:一個二元關係(x, y), 有2條訪問路徑:通過x來訪問y(x-&>y), 和通過y來訪問x(y-&>x)。由此我們可以推斷,一個n元關係的訪問路徑總數為n的階乘(1×2...×n)。 如何在計算機中實現一個n元關係的所有訪問路徑?最直接的想法就是用一張二維表的形式來表現一個Relation:表的每一行代表了這個Relation的一個元組(Tuple), 而每一列對應一個域(Domain);每一行可通過一個獨一無二的值唯一指定,包含這些值的域稱為主碼(Primary Key)(參見圖5,主碼域標有下劃線)。
這裡存在的問題是Domain很多時候對應的不是單值,圖5中,「包含公司」這列說明,一個集團可以擁有多家公司。當然你可以將所有公司到保存在一個Domain中, 用逗號將它們區分開。然而如果一個公司下又可以有多個部門(如「包含部門」),這種情況下你會發現很難在一張表中表現哪個部門對應哪個公司。 如果在「包含公司」這個域中保存的是一個指針,指向其所包含的所有公司,然後公司再保存指向部門的指針,這就又回到導航資料庫了, 即還是限定了訪問路徑,無法實現對稱探索。
圖5. 關係模型規範化解決這個問題的辦法是通過對關係模型進行規範化(Normalize),具體過程如下:將那些多值的Domain剝離出來,為之建立一個獨立的Relation, 這個Relation的主碼是一個複合主碼,其中一部分是來自父Relation的主碼;依次執行相同的操作,直到所有的Relation都只含有單值Domain為止。 我們對圖5中上面的Relation進行規範化操作後便得到下面的3個Relation: Group和Company間是一對多的關係,體現的是一種層級結構; Company和Department之間是多對多關係,體現的是一種網狀結構。通過這種轉換後,你會發現對稱探索的能力被保留了下來, 邏輯上,你可通過任何已知的屬性訪問剩下未知屬性,不需要指針指引。
接下來的問題是如何將這3張二維表(Relation)保存到磁碟上。最簡單的想法是分別以3個文件保存,這當然是對的,只是會面臨嚴重的性能問題。 例如:你想取得部門名為「IT部1」的集團名和公司名,那麼你必須依次打開Department,Company,和Group對應的3個文件, 並對文件中包含的條目進行逐一比對。這種演算法效率顯然不夠高,而且一旦數據量變得很大,這種資料庫將變得無法操作。
避免這種全文件掃描的辦法是先將文件分成更小的單元,稱之為「頁」(Page),一個Page的大小是恆定的,一般設為4KB;然後對這些Page建立索引, 根據索引能快速獲知滿足條件的數據被保存在哪些Page中。資料庫索引的工作原理和查字典是完全一樣的,像漢語字典就有好幾個索引:讀音,部首,筆畫等等; 每種索引的編排方式都不同,但最終一定是指向一個頁碼。資料庫的索引也可以用不同技術基於不同的Domain去建立。 這裡只介紹一種使用最廣泛的索引技術——平衡二叉樹(參見圖6)。
圖6. 平衡二叉樹圖6中的樹形結構每個節點是一個Page,Page內部保存我們要查找的部門名字,假設我們的Page容量很小,根節點只保存了兩個部門名字: 「IT部1」和「財務部」。我們定義大於等於「IT部1」且小於「財務部」的部門名保存在根節點的左孩子節點中;大於等於「財務部」的部門名保存在右孩子節點中。 這樣我們的樹的第二層節點中的第一個Page保存了3個部門的名字,其中第一個值「IT部1」其對應的指針直接指向實際的數據記錄—— 表Department中滿足部門名字是「IT部1」的行。基於平衡二叉樹,我們的查詢只需讀取3個Page。當獲取對應的集團主碼和公司主碼後,以同樣的方式, 我們可以獲取公司名和集團名。
怎麼來比較部門名的大小完全可以由你自己設定,這裡根據英文字母的排列順序,如果是漢字則取其拼音的首字母。
平衡二叉樹之所以被冠之「平衡」是因為它左右兩邊的層級保持一致,一旦達到這種平衡效果,所有的查詢都是二分查找,演算法複雜度為O(logn)。 但維持左右平衡並不是件容易的事情,如果數據在一段時間內有插入,又有刪除,那麼你得仔細的調整這棵樹使其永遠保持平衡。實際上, 每次的插入和刪除動作都是對這組數據的一次重新排序,平衡二叉樹能做到對這種重新排序操作的演算法複雜度也在O(logn)。 從這個意義上說「平衡」具有更加深遠的意義,即所有訪問路徑上的性能平衡,這使它成為實現關係型資料庫最實用、最基礎的數據結構。
進一步思考平衡二叉樹,你會得出一個有趣的結論:平衡二叉樹是一個層級結構,它的物理實現也是個導航型資料庫。 一個更加抽象化的物理模型也就具有更廣泛的通用性。導航型資料庫相對於平衡二叉樹正如層級數據模型之對於關係型模型。
回到一開始的問題,實現關係型模型到底有多難?答案是:非常難。我們舉得平衡二叉樹的例子也許並沒有讓你生畏, 那只是因為我們遺漏了太多的工程細節,例如:範圍查詢如何實現,節點動態分裂,索引同步更新,並發控制,等等。 然而我們已經知道要實現對稱探索,並且保證一定的性能,我們需對涉及查詢的多個Domain建立索引。如果不那麼做, 你就無法避免全表掃描帶來的資源侵吞;而如果你這麼做了,你在插入和刪除數據的時候又得兼顧對這些索引的同步更新,以保持數據的一致性。
每個索引本質上就是一個導航型資料庫,索引的自由建立意味著關係型資料庫要成為導航型資料庫一個高層次的抽象, 它要負責協調多個導航型資料庫的一致性。在上世紀70年代初,在硬體剛好能承受導航型資料庫的年代裡,這種設想僅僅是一種美好的願景。 然而摩爾定律最終讓這一切成為現實,10年後,硬體的性能終於能夠承載起關係型資料庫。從某種意義上說,ORACLE可能當時正好撞上了風口。
關係模型之上是否還可以再抽象?這是個有趣的問題,我不知道數學之上是否還可以抽象,如果數學已經是這個世界最高層次的抽象, 那麼關係模型也就無法再抽象了。事實也證明在關係模型之後,出現的許多資料庫模型反而都是關係模型的具象化, 這其中最為著名的便是實體-關係數據模型。
實體-關係數據模型在Codd提出關係模型的6年後,另一篇論文對關係型資料庫的發展起到了非常重要作用。這便是由陳品山博士在1976年發表的論文: "The Entity-Relationship Model"
實體-關係數據模型(E-R模型)為設計資料庫提供了一種更為直觀的描述。如果說Codd的靈感來源於數學,那麼品山的靈感一定來源於自然語言。 事實上,品山自己也提到過中文對其思維方式的影響。因此,我們不妨將E-R模型和自然語言作一個類比。
自然語言E-R模型對象普通名詞Entity Type專有名詞Entity及物動詞Relationship Type形容詞Attribute for Entity副詞Attribute for Relationship圖7.E-R圖圖7是一個E-R圖的例子,描述一個現實中的商業行為:上海的客戶A購買了3個商品B。客戶和商品是Entity Type(用方框表示), 客戶A和商品B分別是其對應的Entity; 如果通過客戶名能唯一確定一個客戶,那麼客戶名是主屬性(橢圓加下劃線),地址為一般屬性(橢圓); 客戶和商品通過「購買」這個行為聯繫在一起,「購買」是Relationship Type(用菱形表示),一般情況同樣的商品可以銷售給不同的客戶, 同一個客戶也可以購買不同的商品,因此這裡是個多對多(m:n)的Relationship;「數量」是Relationship的一個屬性,用於描述此次購買行為。
E-R模型非常的直觀,並且易於理解,這源於它和自然語言良好的兼容性。將E-R模型轉換成關係型模型也很直接, 你只要將Entity和Relationship分別對應到一個Relation就可以了,於是便有Entity Relation和Relationship Relation, 而且能很自然的達到3範式,這個在關係模型中需要通過規範化操作(Normalization)去實現。
客戶(客戶名,地址)
商品(商品名)
購買(客戶名,商品名,數量)
Relation和Relationship有什麼區別?這個問題從數學角度更容易理解: Relation對Domain是有順序要求的, (a, b, c)與(b, a, c)是不一樣的;而Relationship沒有這方面的要求。 E-R模型中的Relationship是指n個Entity之間的關係(n&>=1),而對Entity沒有作順序要求。
實體-關係數據模型更多的是以E-R圖為世人所熟悉。一方面對於業務人員來說,它非常直觀便於掌握;另一方面,它能很容易的對應到關係型模型, 因此也無須為它再單獨設計一個物理模型。E-R模型就這樣介於概念模型和邏輯模型之間。實際上,長期以來人們已經將E-R模型等價於概念模型, 或者更確切的說是關係型資料庫的概念模型。
然而當開發人員將E-R模型轉換成關係模型的時候,有時候很難區分Entity Relation和Relationship Relation。 這也可以從自然語言中名詞變動詞,或者動詞變名詞等生動活躍的語法中體現,這時候準確理解它們需要結合一定的語境。例如:在圖7中, 如果你只將「購買」理解成一種行為顯然是不夠的(不貼合商業語境),一般情況下,會將「購買」這個Relationship Type具象成一個邏輯的Entity——銷售訂單, 這樣就符合商業語境了(參見圖8)。這裡的原因在於商業組織本身就是一個信息系統(即使在沒有計算機系統之前),它已經經過一層信息化的抽象,形成了其固有的溝通語境。 它並不完全等同於自然語言溝通系統,因此在很多情況下直接比對到關係模型反而更加簡單。
圖8.現實中銷售活動的E-R圖仔細觀察上圖中用E-R圖描繪的一個典型銷售活動,並嘗試用我們的自然語言去闡述它。你也許會驚訝的發現E-R模型和自然語言共享著一些本源性的東西。 我們的自然語言本身就是對現實世界的一種模型化,這種本源性的東西一直紮根在人類的思維中,並指導著人類認識這個世界。 如果有可能讓E-R模型變成一個邏輯模型,進而擁有自己的物理模型實現,那麼我們是否可以讓計算機變得更像人腦? 現代的物理學向我們證明宇宙是建立在數學之上的,然而宇宙中產生的智慧又是反應數學的一個最生動的具象。 E-R模型通過將關係模型印射到自然語言降低了其通用性,然而這是否能讓以E-R模型為邏輯模型的資料庫在特定領域發揮出更好的優勢呢? MDB最初就是基於上述的想法和衝動去搭建的,關於這部分內容我們會在後續的博客中單獨介紹。
後續的發展接下來資料庫模型的發展可簡單歸結為2個方向:其一是繼續沿著具象化的道路前進;其二則是針對特定應用領域的性能優化。
具象化方向在這個方向上,最有影響力的便是對象模型(Object Model)。對象模型是伴隨著面向對象的編程(Object-Oriented Programming)一起被提出的, 然而在實際應用過程中,對象模型並沒有像OO-Programming那樣風靡。這是可以想像的,對象模型相對於關係模型的進一步具象化使得「對稱探索」變得不可能。 對象模型更多的是給程序員帶來了方便,這樣他們可以有效減少大量管道代碼(那些用於將數據格式轉換成關係模型的代碼),但在其他方面看不出它除了限制外還能帶來什麼。 在後續的發展過程中,對象模型的影響力主要體現在對SQL語言的對象化擴展以及眾多的ORM(Object-Relational Mappings)框架, 但卻絲毫沒有撼動關係模型和關係型資料庫的地位。
性能優化方向性能是資料庫發展的第一推動力。在過去30多年裡,摩爾定律一直是性能最有力的保障, 然而互聯網時代的海量數據以及幾何級的增長速度使得摩爾定律帶來的性能紅利猶如杯水車薪,更何況摩爾定律似乎也到了強弩之末。 這讓關係模型再次受限於硬體,然而我們似乎已經掌握了應對之策——分散式模型,這也是迄今為止對關係型資料庫最大的一次衝擊。 我們會在這個系列的第四篇博客中詳細介紹分散式資料庫模型,在這之前,我們先關注另一個曾經在性能方向引起波動的數據模型, 這便是下一篇博客中的內容——《OLAP浪潮》。
附錄:資料庫發展時間線圖9. 資料庫發展時間線每天查一遍因為最終一致性導致的各種崩潰、異常、死鎖之後你就知道為什麼事務是個好東西了。不過其實我並不喜歡SQL。過幾天準備寫篇文章講一下VLCP當中的基於No-SQL(目前是Redis或者ZooKeeper)的資料庫ObjectDB的設計,如何實現帶有完整事務性的關聯查詢、關聯寫入和更新推送的——寫性能雖然只有幾千qps,但是好歹對,而且節約了大量讀的開銷。(準確來說應該是有重疊的或者從同一進程的寫入只有幾千,從分散式的client寫不同的key的組合是不會降低性能的)
HBase沒有Schema,自由是自由了,但是要打交道只能Put,Get,Delete和Scan,拿出來的都是byte[],常用的各種數據類型都得自己去編碼解碼,比如如何表示布爾類型,是用二進位01還是用ASCII碼的"0","1",日期時間類型是存unix time還是一個long,數字是有符號數還是無符號數,都沒有地方定義。
但是關係型模型就不一樣了,包含元數據信息,提供各種數據類型,以及的操作和函數,可以方便地進行多表關聯,寫一個SQL就能把數據查出來。
原來關係型數據的問題一個是Schema的限制不靈活,一個是不能橫向伸縮,尤其是不能自動Sharding,NOSQL解決的是這個問題。個人看法
還是離不開建多表的習慣
只要表一多總牽扯到關聯,於是乎傳統關係型的需求都又茂出來了所以大象生態圈總會茂一堆項目支持傳統資料庫操作試過HBase直接建一大表 暴力避免join
就是transaction不太好使其實沒為什麼的 也沒什麼書包好拋就是需求促使關係模型其實不是關鍵,關鍵是支持的SQL特性
關係是用來保持事務和並發的正確性的,顯然大家又重新意識到,這種事情讓程序員寫C++來保證是多麼的不靠譜。
最好的資料庫,常用的功能都應該提供,但要留給用戶自己去選擇。比如不需要關係的,就不勾選關係功能,這樣資料庫的性能會更高。
現在市面的資料庫,性能高的缺乏功能,功能多的又無法手動關閉不需要的功從而導致很多沒必要的性能損失。1. NoSQL表達能力強前提是使用者對其優劣勢有清楚的了解,等於給一張白紙和畫筆能畫出最美的畫卷,但是人得夠牛,早期大公司優秀程序員能做到隨著用的人越來越多就很難做到了,現在得給一些畫本來約束,按著畫本描,這個約束就是早已流行的SQL語言,大家都會。
2. 樓主提到了索引,NoSQL擴展一般基於分片,當一個表被分成了很多片之後為其建索引就變成了一個分散式事務的問題,如何數據和索引保持一致性就擺在了NoSQL面前,而分散式事務在關係資料庫領域已經研究多年,借用下經驗也很正常,然後就是全面的分散式事務支持。亂說一下,NoSQL和關係最後殊途同歸,會逐漸爬到同一個山頂,NoSQL的道路更陡峭。開發個程序,一般用戶數據量並不大,多數用的mysql這種,像redis這種kv資料庫緩存沒什麼用,如果那天業務量突然爆發了,不用改程序就支持資料庫轉換成kv存儲實現高並發,這個是很多人的追求的,是很多互聯網公司的增長需求,兼容sql對業務程序用戶量的增長很重要(重新開發程序意味著高成本不利競爭),nosql本身的應用範圍的擴大也很有幫助(對於低並發nosql作用不大)。
從各種管理系統程序開發來看,多數業務可以很好地使用sql描述,在程序中使用sql支持的orm也是利於工程化對用戶友好,而傳統sql很慢,所以發展出了很多類似redis的kv系統,這種kv系統分散式好用、速度快,但對用戶不友好,編程時也很費勁。
各個行業需求不一樣,sql是一種通用工具,是標準化操作語言,通用性遠高於kv這種二進位01,但kv速度最快,易於拆分。
如何把sql映射到分散式的kv系統上,是個很關鍵的問題,如果解決了這個痛點,nosql發展空間很大。
使用這種兼容設計sql表時,需要注意,不要用自增主鍵,不要用觸發器,不要用存儲過程,不要用外鍵,用冗餘欄位代替外鍵,實體化視圖,級聯更新時要注意同步問題。
高伸縮性,軟體在十個人和十億人訪問時,只需要水平擴展加機器,如果在雲平台可以動態申請資源,這樣的軟體是大家追求的,sql和kv結合容易實現這一點。
最終傳統資料庫和nosql新型存儲又在兼容sql上找到了共同點。
如果早年關係型資料庫已經很好地處理了分散式場景,相信 NoSQL 根本不會發生。NoSQL 是不得已而為之的產物。而現在分散式關係型資料庫的各種核心問題的解答逐漸明朗。
都能追到女神了,還要充氣娃娃作甚?本質上是因為技術下潛了, 現在的軟體工程需要的是95%"通才" + 5%專才, 之所以給"通才"打上""是因為它的意義跟廣義上認為的"人才"有很大差距.
上面很多同學也說了, 這是因為程序員水平而導致的, 我覺得這個觀點是正確的, 只是論據有點那麼的主觀, 導致水平下降的原因, 應該是"流水線" vs "手工作坊"這個轉變導致的.
要規模化+市場化就必須模塊化+標準化, 而正是這個直接導致了批量生產程序員的巨大需求產生, 這個巨大需求的產生必然導致了普遍水平的下降, 然後又因為標準化彌補了水平下降.
所以"又"開始支持, 只是一種殊途同歸而已, 數據肯定是有關係的, 只在於冗餘的多少.
表現層: Big Bang -&> SQL -&> noSQL -&> Not just SQL -&> Not yet SQL -&> SQL
底層: who cares? PHP是最好的語言!
nosql =not only sql
長久以來關係資料庫的最明顯的痛點不外乎以下兩點1.scale2.容錯不好,分散式事務基本不可用。為了彌補以上問題,幾乎現在成規模的互聯網公司都有自己的一套DAL(MySQL Sharding/Proxy),可這基本上是一個馬後炮的方案。還有一個現象就是 互聯網公司對 關係資料庫的使用方式越來越像一個KV系統了(基本沒有複雜查詢)那麼成熟no sql (HBase Cassandra Mongo)解決了哪些問題?scale 大部分no sql系統都能夠非常好的解決這一類問題, 集群規模上千台是沒有任何壓力的。這類系統在設計上主要有2大類吧(有中心節點,無中心節點)。HBase 源於google bigtable 相當於在hdfs上面做了一個分散式索引層。擴展不是問題。多副本能夠保證數據可靠。那麼再回過頭來看看資料庫的本質的東西 資料庫與文件系統最本質的區別就是 有Transaction的能力。在分散式系統中做到這個很不容易(2pc,3pc raft, paxos)。在一個SQL表現力很強(要不分也不會有Hive ,Impala)。基本上樸素的數據分析或者說規律性的分析用 SQL完全能夠搞定。所以關係模型如何能夠在分散式系統下還能夠保持這些優秀的特性New SQL 最好選擇啊!
歷史總是螺旋上升的。早先人們覺得NoSQL資料庫是未來,但事實證明那幾家NoSQL做的沒有想像中的好,給不了別人花大力氣遷移過去的理由。後面人們可能又發現這個事情也不是完全不能做,於是又有人進行了嘗試。至於這一次是否能擁有未來,還要拭目以待。
很簡單:如果有一個好用的SQL幹嘛不用。。。
以前是因為做不到(足夠好),如果能做到滿足需求,那上唄。
同理,協程/線程如果代價足夠小,幹嘛還要用非阻塞+多路復用?推薦閱讀:
※適合初學者學習資料庫的書有哪些較好的?
※MySQL有什麼推薦的學習書籍?
※多線程並發訪問資料庫中不同記錄時應該採用什麼辦法?
※什麼情況下,需要使用分散式資料庫?
※產品運營,如何做出一份優秀數據報表?