摘 要:圖形數(shù)據(jù)庫支持C/S結(jié)構(gòu)與內(nèi)嵌式部署2種方式,而內(nèi)嵌式部署因使用簡單方便而廣受關(guān)注。以教育領(lǐng)域中論文作者合作關(guān)系圖譜為例對圖形數(shù)據(jù)庫的嵌入式應(yīng)用進(jìn)行研究,提供一種快速、動態(tài)的學(xué)術(shù)合作關(guān)系存儲方法。研究表明圖形數(shù)據(jù)在數(shù)據(jù)庫創(chuàng)建、查詢、更新等方面表現(xiàn)出很高的易用性,特別特別適合處理大量復(fù)雜、動態(tài)、互連接、低結(jié)構(gòu)化的數(shù)據(jù),是一種解決社交網(wǎng)絡(luò)、信息可視化等領(lǐng)域海量關(guān)聯(lián)數(shù)據(jù)存儲的有效方法。
關(guān)鍵詞:圖形數(shù)據(jù)庫; 人物關(guān)系圖譜; 關(guān)聯(lián)數(shù)據(jù); Neo4j
中圖分類號:TN91934 文獻(xiàn)標(biāo)識碼:A 文章編號:1004
圖狀模型是對層次模型的進(jìn)一步發(fā)展,其本質(zhì)是將數(shù)據(jù)組織為圖的形式,對數(shù)據(jù)庫系統(tǒng)的各種增、刪、改、查操作變成對圖的遍歷與搜索。作為NoSQL數(shù)據(jù)庫的一種,圖數(shù)據(jù)庫很長時間多局限于學(xué)術(shù)與實驗室,隨著Web 2.0的發(fā)展,數(shù)據(jù)間的關(guān)聯(lián)與數(shù)據(jù)變得同等重要。在社交網(wǎng)絡(luò)Facebook、電子商務(wù)、資源檢索等領(lǐng)域[1]存在大量的關(guān)聯(lián)數(shù)據(jù),急切需要一種能夠處理復(fù)雜關(guān)聯(lián)的存儲技術(shù),圖形數(shù)據(jù)庫才逐漸從實驗室走出,因為采用圖形數(shù)據(jù)來存儲和計算這些海量的數(shù)據(jù)更加有效。這極大地推動了圖形數(shù)據(jù)庫的快速發(fā)展。 現(xiàn)在比較成熟的圖像數(shù)據(jù)庫包括 Twitter 的FlockDB,以及開源項目中的Neo4j 和Infogrid等。
Neo4j是基于Java的圖形數(shù)據(jù)庫[2],它遵循著屬性圖形數(shù)據(jù)模型。相對于關(guān)系數(shù)據(jù)模型來說,Neo4j重點解決了擁有大量連接的傳統(tǒng)RDBMS在查詢時出現(xiàn)的性能衰退問題。通過圍繞圖形進(jìn)行數(shù)據(jù)建模,Neo4j會以相同的速度遍歷結(jié)點與邊,其遍歷速度與構(gòu)成圖形的數(shù)據(jù)量沒有任何關(guān)系。此外,Neo4j還提供了非??斓膱D形算法、推薦系統(tǒng)和OLAP風(fēng)格的分析,而這一切在目前的RDBMS系統(tǒng)中都是無法實現(xiàn)的。Neo4j是一個高性能、高可抗靠性、可擴(kuò)展的、完全兼容ACID的圖數(shù)據(jù)庫。它完全由Java語言實現(xiàn),能夠部署到多種系統(tǒng)上。在Neo4j中,數(shù)據(jù)以一種針對圖網(wǎng)絡(luò)進(jìn)行過優(yōu)化的格式保存在磁盤上。Neo4j的內(nèi)核是一種極快的圖引擎,具有數(shù)據(jù)庫產(chǎn)品期望的所有特性,如恢復(fù)、兩階段提交、符合XA等。下面我們將針對圖形數(shù)據(jù)庫Neo4j的實際應(yīng)用進(jìn)行闡述,并與關(guān)系數(shù)據(jù)庫進(jìn)行比較。
1 Neo4j的應(yīng)用模式
Neo4j支持2種應(yīng)用模式[3],分別是內(nèi)嵌模式和服務(wù)器模式。內(nèi)嵌模式將數(shù)據(jù)庫文件內(nèi)嵌到應(yīng)用程序中,作為程序的一個單獨數(shù)據(jù)庫,供應(yīng)用程序內(nèi)部自行調(diào)用。服務(wù)器模式將Neo4j作為單獨的服務(wù)器進(jìn)行部署,利用REST風(fēng)格的方式進(jìn)行調(diào)用,服務(wù)器模式時,系統(tǒng)由2部分組成:
(1) 客戶端通過RMI方式發(fā)送命令到服務(wù)器;
(2) 服務(wù)器接收并處理這些命令,返回執(zhí)行后的結(jié)果。在這種應(yīng)用模式下,Neo4j通過Cypher查詢語言來進(jìn)行圖的搜索與查詢操作。Cypher是一個描述性的圖查詢語言,允許不必編寫圖形結(jié)構(gòu)的遍歷代碼就可實現(xiàn)對圖的存儲和效率查詢。Cypher不同于Java或腳本語言,而更類似于關(guān)系數(shù)據(jù)庫中的SQL語言。
在內(nèi)嵌應(yīng)用程序的應(yīng)用模式下,應(yīng)用程序直接使用Neo4j數(shù)據(jù)庫,開發(fā)者可以通過JavaAPI直接與圖模型交互,這個API提供了非常靈活的數(shù)據(jù)結(jié)構(gòu)。通俗的說就是通過直接編碼的方式與Neo4j圖數(shù)據(jù)庫交互。接下來我們將主要闡述內(nèi)嵌應(yīng)用模式。
2 Neo4j內(nèi)嵌模式數(shù)據(jù)庫創(chuàng)建
下面通過一個簡單的例子來展示Neo4j的基本功能。圖1的這個小型圖是文獻(xiàn)作者合作關(guān)系與論文引用關(guān)系圖譜,共有四種關(guān)系類型,分別是WRITE,WRITE_BY,COAUTHOR,CITE和CITE_BY。
圖1 論文作者合作關(guān)系與論文引用創(chuàng)建圖形數(shù)據(jù)庫的步驟如下(Java表示):
Step 1:使用枚舉來表示結(jié)點間的關(guān)系類型:
enum Relationships implements RelationshipType { COAUTHOR,WRITE,CITE }
Step 2:調(diào)用內(nèi)嵌模式創(chuàng)建接口,在DB_PATH路徑下建立一個新的圖數(shù)據(jù)庫,該路徑人為指定,如果數(shù)據(jù)庫已經(jīng)存在則直接打開,否則新建數(shù)據(jù)庫。
graphDb = new EmbeddedGraphDatabase(DB_PATH);
Step 3:創(chuàng)建圖,存儲作者、論文及其內(nèi)在關(guān)聯(lián),對圖的所有修改均放在事務(wù)中,從而保證數(shù)據(jù)的完整性。
public void createGraph() {
Transaction tx = graphDb.beginTx();
try {
Node Miche = graphDb.createNode(); Miche.setProperty(\"name\", \"Miche\");
Node Robert = graphDb.createNode();Robert.setProperty(\"name\", \"Robert\");
Node Mike = graphDb.createNode();Mike.setProperty(\"name\", \"Mike\");
Node Jim = graphDb.createNode();Jim.setProperty(\"name\", \"Jim\");
Node rc = graphDb.createNode();rc.setProperty(\"name\", \"Reading Comprehension\");
Node ew = graphDb.createNode();ew.setProperty(\"name\", \"English Writing\");
Node er = graphDb.createNode();er.setProperty(\"name\", \"English Reading\");
Miche.createRelationshipTo(Robert, Relationships.COAUTHOR);
Miche.createRelationshipTo(Mike, Relationships.COAUTHOR);
Mike.createRelationshipTo(Jim, Relationships.COAUTHOR);
Robert.createRelationshipTo(Jim, Relationships.COAUTHOR);
Miche.createRelationshipTo(Robert, Relationships.COAUTHOR);
Mike.createRelationshipTo(rc, Relationships.WRITE);
Mike.createRelationshipTo(ew, Relationships.WRITE);
Jim.createRelationshipTo(ew, Relationships.WRITE);
Jim.createRelationshipTo(er, Relationships.WRITE);
rc.createRelationshipTo(ew, Relationships.CITE);
ew.createRelationshipTo(er, Relationships.CITE);
tx.success();
} catch (Exception e) {tx.failure();} finally {tx.finish(); }}
在事務(wù)提交過程中,tx.success()只是測試事務(wù)是否能夠成功提交,并沒有真正提交事務(wù)。事務(wù)的最終提交由tx.finish()完成。
3 Neo4j內(nèi)嵌模式數(shù)據(jù)庫檢索
在數(shù)據(jù)庫創(chuàng)建后,可以進(jìn)行查詢、插入、更新、刪除等基本操作,下面通過一個簡單的問題“Mike寫了哪些論文?”來描述Neo4j圖數(shù)據(jù)庫的查找功能。這里,只需查看“Mike”結(jié)點的“WRITE”關(guān)系便可以找出他寫過的論文:
for (Relationship rel : Mike.getRelationships(Relationships.WRITE)) {
Node paper = rel.getOtherNode(Mike);
System.out.println(paper.getProperty(\"name\"));}
檢索結(jié)果為“Reading Comprehension”和“English Writing”。這只是簡單的查詢,對于復(fù)雜查詢,則需借助于功能強(qiáng)大Neo4j TraverserAPI接口,它可以完成非常復(fù)雜的遍歷描述和過濾器。它由Traverser和ReturnableEvaluator模塊組成,前者計算StopEvaluator來獲知何時停止,后者則用于計算在結(jié)果中應(yīng)該包含哪些結(jié)點。此外,還可以指定要遍歷關(guān)系的類型和方向。Traverser實現(xiàn)了Java的Iterator接口,負(fù)責(zé)延遲加載和遍歷整個圖,在結(jié)點被首次要求訪問時進(jìn)行。它還內(nèi)置了一些常用的Evaluator和缺省值,上面的查詢采用TraverserAPI時的流程如下:
Traverser papers = neo.traverse(Order.BREADTH_FIRST,StopEvaluator.DEPTH_ONE,
ReturnableEvaluator.ALL_BUT_START_NODE, Relationships.WRITE, Direction.BOTH);
for (Node paper : papers) { System.out.println(paper.getProperty(\"name\"));
TraverserAPI在繼續(xù)訪問更深一級的結(jié)點之前首先從起點訪問處于同一深度的所有結(jié)點(Order.BREADTH_FIRST),在深度為1的一次遍歷后停止(StopEvaluator.DEPTH_ONE),然后返回除了起點(\"Mike\")之外的所有結(jié)點(ReturnableEvaluator.ALL_BUT_START_NODE)。在兩個方向只遍歷類型為WRITE的關(guān)系。通過使用TraverserAPI可以完成非常復(fù)雜的遍歷操作。
4 結(jié) 語
通過以上實例可以看出,圖形數(shù)據(jù)庫的創(chuàng)建與維護(hù)異常簡單,結(jié)點的屬性可以動態(tài)變化,結(jié)點之間的邊可以也可以自由增減,這對于關(guān)系數(shù)據(jù)庫來講非常困難。可見圖數(shù)據(jù)庫更善于處理大量復(fù)雜、動態(tài)、互鏈接、低結(jié)構(gòu)化的數(shù)據(jù)。在關(guān)系數(shù)據(jù)庫中,這些查詢會導(dǎo)致大量的表鏈接,因此會產(chǎn)生性能上的問題。圖數(shù)據(jù)庫重點解決了擁有大量鏈接的傳統(tǒng) RDBMS在查詢時出現(xiàn)的性能衰退問題。通過圍繞圖形進(jìn)行數(shù)據(jù)建模,圖數(shù)據(jù)庫會以相同的速度遍歷結(jié)點與邊,其遍歷速度與構(gòu)成圖的數(shù)據(jù)量沒有任何關(guān)系。此外,Neo4j還提供了非常快的圖形算法、推薦系統(tǒng)和OLAP風(fēng)格的分析,而這一切在目前的RDBMS系統(tǒng)中都是無法實現(xiàn)的\[4\]。
參 考 文 獻(xiàn)
[1] 于戈.云計算環(huán)境下的大規(guī)模圖數(shù)據(jù)處理技術(shù)\[J\].計算機(jī)學(xué)報,2011(10):17561765.
[2] Anon. Neo4j tutorial \[EB/OL\]. \[20120213\]. http://docs.neo4j.org/chunked/stable/tutorials.html.
[3] Anon. Neo4j API documentation \[EB/OL\]. \[20111118\]. http://api.neo4j.org.
[4] 唐箭,虢莉娟,龔濤.基于云計算的終身教育服務(wù)平臺設(shè)計\[J\].現(xiàn)代電子技術(shù),2010,33(12):4346.
[5] 曾麗君,張紅梅,李中林.云計算及其在軍事上的應(yīng)用探討\[J\].現(xiàn)代電子技術(shù),2009,32(23):2326.
[6] 鄭貴德,陳明.以云計算為后臺的負(fù)載均衡技術(shù)\[J\].現(xiàn)代電子技術(shù),2012,35(9):7780.
[7] 李文娟,那彥.基于云計算及圖像內(nèi)容分析的醫(yī)學(xué)圖像融合方法\[J\].電子科技,2011(3):2226.
[8] 劉曉樂.計算機(jī)云計算及其實現(xiàn)技術(shù)分析\[J\].電子科技,2009(12):100102.
[9] 程飛,黃曦.基于OGRE的三維紅外云仿真\[J\].電子科技,2010(6):47.
[10] 趙廣才,張雪萍.云計算技術(shù)分析及其展望\[J\].電子設(shè)計工程,2011(22):47.
作者簡介: 王余藍(lán) 女,西安交通大學(xué)外國語學(xué)院。研究方向為信息系統(tǒng)、實驗室管理。