在衆多不一樣的數據模型裏,關係數據模型自80年代就處於統治地位,並且有很多實現,如Oracle、MySQL和MSSQL,它們也被稱爲關係數據庫管理系統(RDBMS)。然而,最近隨着關係數據庫使用案例的不斷增長,一些問題也暴露了出來,這主要是由於兩個緣由:數據建模中的一些缺陷和問題,以及在大數據量和多服務器之上進行水平伸縮的限制。兩個趨勢讓這些問題引發了全球軟件社區的重視:php
在應對這些趨勢時,關係數據庫產生了更多的問題。這致使大量解決這些問題某些特定方面的不一樣技術的出現,它們能夠與現有RDBMS相互配合或代替它們 - 亦被稱爲混合持久化(Polyglot Persistence)。數據庫替代品並非新鮮事物,它們已經以對象數據庫(OODBMS)、層次數據庫(如LDAP)等形式存在很長時間了。可是,過去幾年間,出現了大量新項目,它們被統稱爲NOSQL數據庫(NOSQL-databases)html
本文旨在介紹圖形數據庫(Graph Database)在NOSQL運動裏的地位,第二部分則是對Neo4j(一種基於Java的圖形數據庫)的簡介。mysql
NOSQL(Not Only SQL,不限於SQL)是一類範圍很是普遍的持久化解決方案,它們不遵循關係數據庫模型,也不使用SQL做爲查詢語言。git
簡單地講,NOSQL數據庫能夠按照它們的數據模型分紅4類:github
就Voldemort或Tokyo Cabinet這類鍵/值系統而言,最小的建模單元是鍵-值對。對BigTable的克隆品來說,最小建模單元則是包含不一樣個數屬性的元組,至於象CouchDB和MongoDB這樣的文檔庫,最小單元是文檔。圖形數據庫則乾脆把整個數據集建模成一個大型稠密的網絡結構。算法
在此,讓咱們深刻檢閱NOSQL數據庫的兩個有意思的方面:伸縮性和複雜度。sql
爲了保證數據完整性,大多數經典數據庫系統都是以事務爲基礎的。這全方位保證了數據管理中數據的一致性。這些事務特性也被稱爲ACID(A表明原子性、C表示一致性、I是隔離性、D則爲持久性)。然而,ACID兼容系統的向外擴展已經表現爲一個問題。在分佈式系統中,高可用性不一樣方面之間產生的衝突沒有徹底獲得解決 - 亦稱CAP法則:mongodb
CAP法則假定向外擴展的3個不一樣方面中只有兩個能夠同時徹底實現。數據庫
爲了能處理大型分佈式系統,讓咱們深刻了解所採用的不一樣CAP特徵。apache
不少NOSQL數據庫首先已經放寬了對於一致性(C)的要求,以期獲得更好的可用性(A)和分區容忍性(P)。這產生了被稱爲BASE(基本(B)可用性(A)、軟狀態(S)、最終一致性(E))的系統。它們沒有經典意義上的事務,而且在數據模型上引入了約束,以支持更好的分區模式(如Dynamo系統等)。關於CAP、ACID和BASE的更深刻討論能夠在這篇介紹裏找到。
蛋白質同源網絡(Protein Homology Network),感謝Alex Adai:細胞和分子生物學院 - 德州大學
數據和系統的互聯性增長產生了一種沒法用簡單明瞭或領域無關(domain-independent)方式進行伸縮和自動分區的稠密數據集,甚至連Todd Hoff也提到了這一問題。關於大型複雜數據集的可視化內容能夠訪問可視化複雜度(Visual Complexity)。
在把關係數據模型扔進故紙堆以前,咱們不該該忘記關係數據庫系統成功的一個緣由是遵守E.F. Codd的想法,關係數據模型經過規範化的手段原則上可以建模任何數據結構且沒有信息冗餘和丟失。建模完成以後,就可使用SQL以一種很是強大的方式插入、修改和查詢數據。甚至有些數據庫,爲了插入速度或針對不一樣使用狀況(如OLTP、OLAP、Web應用或報表)的多維查詢(星形模式),對模式實現了優化。
這只是理論。然而在實踐中,RDBM遇到了前面提到的CAP問題的限制,以及由高性能查詢實現而產生的問題:聯結大量表、深度嵌套的SQL查詢。其餘問題包括伸縮性、隨時間的模式演變,樹形結構的建模,半結構化數據,層級和網絡等。
關係模型也很難適應當前軟件開發的方法,如面向對象和動態語言,這被稱爲對象-關係阻抗失配。由此,象Java的Hibernate這樣的ORM層被開發了出來,並且被應用到這種混合環境裏。它們當然簡化了把對象模型映射到關係數據模型的任務,可是沒有優化查詢的性能。尤爲是半結構化數據每每被建模成具備許多列的大型表,其中不少行的許多列是空的(稀疏表),這致使了拙劣的性能。甚至做爲替代方法,把這些結構建模成大量的聯結表,也有問題。由於RDBMS中的聯結是一種很是昂貴的集合操做。
看看領域模型在數據結構上的方案,有兩個主流學派 - RDBMS採用的關係方法和圖 - 即網絡結構,如語義網用到的。
儘管圖結構在理論上甚至能夠用RDBMS規範化,但因爲關係數據庫的實現特色,對於象文件樹這樣的遞歸結構和象社交圖這樣的網絡結構有嚴重的查詢性能影響。網絡關係上的每次操做都會致使RDBMS上的一次"聯結"操做,以兩個表的主鍵集合間的集合操做來實現 ,這種操做不只緩慢而且沒法隨着這些表中元組數量的增長而伸縮。
屬性圖形(Property Graph)的基本術語
在圖的領域,並無一套被普遍接受的術語,存在着不少不一樣類型的圖模型。可是,有人致力於建立一種屬性圖形模型(Property Graph Model),以期統一大多數不一樣的圖實現。按照該模型,屬性圖裏信息的建模使用3種構造單元:
更特殊的是,這個模型是一個被標記和標向的屬性多重圖(multigraph)。被標記的圖每條邊都有一個標籤,它被用來做爲那條邊的類型。有向圖容許邊有一個固定的方向,從末或源節點到首或目標節點。屬性圖容許每一個節點和邊有一組可變的屬性列表,其中的屬性是關聯某個名字的值,簡化了圖形結構。多重圖容許兩個節點之間存在多條邊。這意味着兩個節點能夠由不一樣邊鏈接屢次,即便兩條邊有相同的尾、頭和標記。
下圖顯示了一個被標記的小型屬性圖。
TinkerPop有關的小型人員圖
圖論的巨大用途被獲得了承認,它跟不一樣領域的不少問題都有關聯。最經常使用的圖論算法包括各類類型的最短路徑計算、測地線(Geodesic Path)、集中度測量(如PageRank、特徵向量集中度、親密度、關係度、HITS等)。然而,在不少狀況下,這些算法的應用僅限制於研究,由於實際中沒有任何可用於產品環境下的高性能圖形數據庫實現。幸運的是,近些年狀況有所改觀。有幾個項目已經被開發出來,並且目標直指24/7的產品環境:
下圖展現了在複雜度和伸縮性方面背景下的主要NOSQL分類的位置。
關於「規模擴展和複雜度擴展的比較」的更多內容,請閱讀Emil Eifrem的博文。
Neo4j是一個用Java實現、徹底兼容ACID的圖形數據庫。數據以一種針對圖形網絡進行過優化的格式保存在磁盤上。Neo4j的內核是一種極快的圖形引擎,具備數據庫產品指望的全部特性,如恢復、兩階段提交、符合XA等。自2003年起,Neo4j就已經被做爲24/7的產品使用。該項目剛剛發佈了1.0版 - 關於伸縮性和社區測試的一個主要里程碑。經過聯機備份實現的高可用性和主從複製目前處於測試階段,預計在下一版本中發佈。Neo4j既可做爲無需任何管理開銷的內嵌數據庫使用;也能夠做爲單獨的服務器使用,在這種使用場景下,它提供了普遍使用的REST接口,可以方便地集成到基於PHP、.NET和JavaScript的環境裏。但本文的重點主要在於討論Neo4j的直接使用。
開發者能夠經過Java-API直接與圖形模型交互,這個API暴露了很是靈活的數據結構。至於象JRuby/Ruby、Scala、Python、Clojure等其餘語言,社區也貢獻了優秀的綁定庫。Neo4j的典型數據特徵:
甚至「傳統」RDBMS應用每每也會包含一些具備挑戰性、很是適合用圖來處理的數據集,如文件夾結構、產品配置、產品組裝和分類、媒體元數據、金融領域的語義交易和欺詐檢測等。
圍繞內核,Neo4j提供了一組可選的組件。其中有支持經過元模型構造圖形結構、SAIL - 一種SparQL兼容的RDF TripleStore實現或一組公共圖形算法的實現。
要是你想將Neo4j做爲單獨的服務器運行,還能夠找到REST包裝器。這很是適合使用LAMP軟件搭建的架構。經過memcached、e-tag和基於Apache的緩存和Web層,REST甚至簡化了大規模讀負荷的伸縮。
要給出確切的性能基準數據很難,由於它們跟底層的硬件、使用的數據集和其餘因素關聯很大。自適應規模的Neo4j無需任何額外的工做即可以處理包含數十億節點、關係和屬性的圖。它的讀性能能夠很輕鬆地實現每毫秒(大約每秒1-2百萬遍歷步驟)遍歷2000關係,這徹底是事務性的,每一個線程都有熱緩存。使用最短路徑計算,Neo4j在處理包含數千個節點的小型圖時,甚至比MySQL快1000倍,隨着圖規模的增長,差距也愈來愈大。
這其中的緣由在於,在Neo4j裏,圖遍歷執行的速度是常數,跟圖的規模大小無關。不象在RDBMS裏常見的聯結操做那樣,這裏不涉及下降性能的集合操做。Neo4j以一種延遲風格遍歷圖 - 節點和關係只有在結果迭代器須要訪問它們的時候纔會被遍歷並返回,對於大規模深度遍歷而言,這極大地提升了性能。
寫速度跟文件系統的查找時間和硬件有很大關係。Ext3文件系統和SSD磁盤是不錯的組合,這會致使每秒大約100,000寫事務操做。
前面已經說過,社交網絡只是表明了圖形數據庫應用的冰山一角,但用它們來做爲例子可讓人很容易理解。爲了闡述Neo4j的基本功能,下面這個小型圖來自黑客帝國這部電影。該圖是用Neo4j的Neoclipse產生的,該插件基於Eclipse RCP: