掃二維碼與項目經(jīng)理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術咨詢/運營咨詢/技術建議/互聯(lián)網(wǎng)交流
大多數(shù)應用程序都是通過疊加一層層的數(shù)據(jù)模型構建而來 。因此每層都面臨問題:如何將其用下一層表示?如:

1. 作為一名開發(fā),觀測現(xiàn)實世界(包括人員、組織 、貨物 、行為、資金流動、傳感器等) ,通過對象或數(shù)據(jù)結構及操作這些數(shù)據(jù)結構的API來對其建模,這些數(shù)據(jù)結構往往特定于該應用
2. 當需要存儲這些數(shù)據(jù)結構時,可采用通用數(shù)據(jù)模型(例如JSON XML文檔、關系數(shù)據(jù)庫中的表或圖模型)來表示
3. DBA接著決定用何種內(nèi)存、磁盤或網(wǎng)絡的 節(jié)格式來表示上述JSON/XML/關系/圖形數(shù)據(jù)。數(shù)據(jù)表示需要支持多種方式的查詢詢、搜索、操作和處理數(shù)據(jù)(系列三時介紹)
4. 在更下一層,硬件工程師則需要考慮用電流、光脈沖、磁場等來表示字節(jié)
復雜的應用程序可能會有更多的中間層:如基于API來構建上層API ,但基本思想一樣:每層都通過提供一個簡潔的數(shù)據(jù)模型來隱藏下層的復雜性。這些抽象機制使得不同團隊可高效協(xié)作,例如數(shù)據(jù)廠商的工程師和使用數(shù)據(jù)庫的開發(fā)很好的協(xié)作。
數(shù)據(jù)模型有很多類型,每種都有其最佳實踐??紤]到數(shù)據(jù)模型對其上的軟件應用有巨大影響( 哪些可以做、不能做),因此需慎重選擇適合業(yè)務的數(shù)據(jù)模型。
本本會介紹一些用于數(shù)據(jù)存儲和查詢的通用數(shù)據(jù)模型 (上面提到的第2點)。尤其,將比較關系模型 、文檔模型和一些基于圖的數(shù)據(jù)模型。還討論多種查詢語言并比較使用場景。
如今SQL是最著名的數(shù)據(jù)模型 ,它基于Edgar Codd 1970年提出的關系模型:數(shù)據(jù)被組織成關系(relations),在SQL中稱為表(table),其中每個關系都是元組(tuples)的無序集合(SQL中稱為行)。
關系模型曾經(jīng)只是理論建議, 很多人懷凝它是否能被高效實現(xiàn)。但20世紀80年代中期,關系數(shù)據(jù)庫管理系統(tǒng)( RDBMS )和SQL已成為大多數(shù)需要存儲、查詢具有某種規(guī)則結構的數(shù)據(jù)的首選工具。關系數(shù)據(jù)庫的主導地位持續(xù)至今已有三十多年,算得上是計算機史的不朽傳奇。
關系數(shù)據(jù)庫核心在于商業(yè)數(shù)據(jù)處理, 20世紀60年代和70年代主要運行在大型計算機。如今來看,用例很常見,主要是:
當時的其他數(shù)據(jù)庫迫使開發(fā)人員考慮數(shù)據(jù)的內(nèi)部表示。關系模型的目標就是將實現(xiàn)細節(jié)隱藏在更簡潔的接口下。20世紀70年代和80代初期,網(wǎng)絡模型和層次模型是兩個主要選擇,但最終關系模型主宰該領域。
對象數(shù)據(jù)庫曾在20世紀80年代后期和90年代初期起起伏伏。XML數(shù)據(jù)庫則出現(xiàn)在21世紀初,但也僅限于利基市場。關系模型的競爭者都曇花一現(xiàn)。
如今關系數(shù)據(jù)庫超出它們最初的商業(yè)數(shù)據(jù)處理范圍,推廣到各種案例:在線發(fā)布、論壇、社
交網(wǎng)絡、電子商務 游戲、 SaaS。
21世紀,NoSQL成為推翻關系模式主導地位的有力競爭者。NoSQL名字不恰當,因為它其實并不代表具體技術,最初只是作為吸引人眼球的Twitter標簽頻頻出現(xiàn)在2009年的開源、分布式及非關系數(shù)據(jù)庫的見面會?,F(xiàn)在很多新興數(shù)據(jù)庫系統(tǒng)總是會打上NoSQL標簽,而其含義也已經(jīng)被逆向重新解釋為“不僅僅是SQL”。
采用NoSQL數(shù)據(jù)庫的驅(qū)動因素:
不同應用程序有不同需求,沒有銀彈技術,可預見的將來,關系數(shù)據(jù)庫仍將繼續(xù)與各種非關系數(shù)據(jù)存儲一起使用,這種思路有時也被稱為混合持久化。
現(xiàn)在大多數(shù)應用開發(fā)都采用OOP編程語言 ,由于兼容性問題,普遍對SQL數(shù)據(jù)模型抱怨:若數(shù)據(jù)存儲在關系表,則應用層代碼中的對象與表、行和列的數(shù)據(jù)庫模型之間需要一個笨拙的轉(zhuǎn)換層。模型之間的脫離有時被稱為阻抗失諧(電子學術語:每個電路的輸入和輸出都有 一定的阻抗(交流電阻) 一個電路的輸出連接到另一個電路的輸入時,若兩個電路的輸出和輸入阻抗匹配,則連接上的功率傳輸將被最大化,阻抗不匹配會導致信號反射和其他故障)。
像Hibernate對象關系映射(ORM) 框架減少了此轉(zhuǎn)換層的樣板代碼,但也無法完全隱藏兩個模型之間差異。
簡歷案例
如下展示了關系模式表示LinkedIn簡歷:
圖一
整個簡歷可通過唯一標識符user id標識。像first_name、last_name字段在每個用戶中只出現(xiàn)一次,所以建模為users表中的列。而大多數(shù)人在他們的職業(yè)中有一個以上工作,且可能有多個教育階段和任意數(shù)量的聯(lián)系信息。用戶與這些項目之間是一對多,可用多種方式表示:
簡歷這樣的數(shù)據(jù)結構,主要是個自包含的文檔( document ),因此用JSON表示非常合適:
面向文檔的數(shù)據(jù)庫(如MongoDB)都支持該數(shù)據(jù)模型。
有人覺得JSON模型減少了應用程序代碼和存儲層之間的阻抗失配。然而,JSON作為數(shù)據(jù)編碼格式也存在問題。缺乏模式常常被認為是一個優(yōu)勢~
JSON表示比關系模式表示的多表模式具有更好的局部性。若要在關系模式中讀取一份簡歷,則:
? 要么執(zhí)行多個查詢(通過user_id查詢每個表)
? 要么在users表及其從屬表之間執(zhí)行混亂的多路聯(lián)結
而JSON表示方法,所有的相關信息都在一個地方,一次查詢即可。
用戶簡歷到用戶的職位、教育歷史和聯(lián)系信息的 對多關系,意味著數(shù)據(jù)存在樹狀結構,JSON表示將該樹結構顯式化,一對多的關系形成樹狀結構:
上面案例的region_id、indu0stry_id 定義為ID ,而非純文本字符串,如"Greater Seattle Area Philanthropy",why?
若用戶界面是可以輸入地區(qū)或行業(yè)的自由文本字段,則將其存儲為純文本字符串更有意義。但擁有地理區(qū)域和行業(yè)的標準化列表,并讓用戶從下拉列表或自動填充器中進行選擇更有優(yōu)勢:
無論是存儲ID or 文本字符串,都涉及內(nèi)容重復問題:
使用ID的好處:對人類沒有任何直接意義,所以永遠不需要直接改變。即使ID標識的信息變化,他也能繼續(xù)保持不變。任何對人類有意義的東西都可能變更。若這些信息被復制 ,則所有副本都得更新。這會導致更多寫開銷,且存在數(shù)據(jù)不一致風險。消除這種重復,也正是數(shù)據(jù)庫規(guī)范化的核心思想。
而這種數(shù)據(jù)規(guī)范化需要表達多對一關系(許多人生活在同一地區(qū), 在同一行業(yè)工作),這并不是很適合文檔模型:
若數(shù)據(jù)庫本身不支持聯(lián)結,則必須在應用程序代碼中,通過對數(shù)據(jù)庫進行多次查詢來模擬聯(lián)結(對于上述例子,地區(qū)和行業(yè)的列表很小且短期內(nèi)不大可能變化, 應用程序可將其緩存在內(nèi)存。但無論如何,聯(lián)結工作其實從數(shù)據(jù)庫轉(zhuǎn)移到了應用層。
即使應用程序的初始版本非常適合采用無聯(lián)結 文檔模型 但隨著應用支持越來越多功能,數(shù)據(jù)也變更互聯(lián)一體化。例如,考慮可能對簡歷進行的變更:
如下圖展示了這些新功能如何定義多對多。每個虛線矩形框數(shù)據(jù)可組織為一個文檔,但指向組織、學校及其他用戶的關系則需表示為引用,并且在查詢時,需要聯(lián)結操作。多對多關系來擴展簡歷:
? ?

我們在微信上24小時期待你的聲音
解答本文疑問/技術咨詢/運營咨詢/技術建議/互聯(lián)網(wǎng)交流