圖數(shù)據(jù)Neo4j導(dǎo)論

隨著社交、電商、金融、零售、物聯(lián)網(wǎng)等行業(yè)的快速發(fā)展,現(xiàn)實(shí)社會(huì)織起了了一張龐大而復(fù)雜的關(guān)系網(wǎng),傳統(tǒng)數(shù)據(jù)庫(kù)很難處理關(guān)系運(yùn)算。大數(shù)據(jù)行業(yè)需要處理的數(shù)據(jù)之間的關(guān)系隨數(shù)據(jù)量呈幾何級(jí)數(shù)增長(zhǎng),亟需一種支持海量復(fù)雜數(shù)據(jù)關(guān)系運(yùn)算的數(shù)據(jù)庫(kù),圖數(shù)據(jù)庫(kù) 應(yīng)運(yùn)而生。

1. 圖數(shù)據(jù)簡(jiǎn)介

1.1 何為圖?

學(xué)過(guò)數(shù)據(jù)結(jié)構(gòu)這么課程的同學(xué)腦海中應(yīng)該或多或少有 的概念。

形式上,圖是頂點(diǎn)(Vertices)和邊(Edge)的集合,用以表現(xiàn)節(jié)點(diǎn)間的接關(guān)聯(lián)關(guān)系;

在圖數(shù)據(jù)庫(kù)的建模中用節(jié)點(diǎn)表示實(shí)體,用邊表現(xiàn)關(guān)系。

image-20220223174338589

在我們的現(xiàn)實(shí)生活中,圖表示的關(guān)系可以說(shuō)是無(wú)處不在。 Gartner定義了商業(yè)世界中5個(gè)最重要的圖——社交、意向消費(fèi)、興趣移動(dòng),并認(rèn)為運(yùn)用這些圖的能力是一個(gè)項(xiàng)”可持續(xù)的競(jìng)爭(zhēng)優(yōu)勢(shì)

1.2 圖數(shù)據(jù)庫(kù) GraphDB

圖數(shù)據(jù)庫(kù)(Graph database)并非指存儲(chǔ)圖片的數(shù)據(jù)庫(kù),而是以 這種數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)和查詢數(shù)據(jù)。

圖形數(shù)據(jù)庫(kù)是一種在線數(shù)據(jù)庫(kù)管理系統(tǒng),具有處理圖形數(shù)據(jù)模型的創(chuàng)建,讀取,更新和刪除(CRUD)操作。

與其他數(shù)據(jù)庫(kù)不同,關(guān)系在圖數(shù)據(jù)庫(kù)中占首要地位。這意味著應(yīng)用程序不必使用外鍵或帶外處理(如MapReduce)來(lái)推斷數(shù)據(jù)的關(guān)聯(lián)關(guān)系。

與關(guān)系數(shù)據(jù)庫(kù)或其他NoSQL數(shù)據(jù)庫(kù)相比,圖數(shù)據(jù)庫(kù)的數(shù)據(jù)模型也更加簡(jiǎn)單,更具表現(xiàn)力。圖形數(shù)據(jù)庫(kù)是為與事務(wù)(OLTP)系統(tǒng)一起使用而構(gòu)建的,并且在設(shè)計(jì)時(shí)考慮了事務(wù)完整性和操作可用性。

根據(jù)存儲(chǔ)和處理模型不同,市面上圖數(shù)據(jù)庫(kù)也有一些區(qū)分。

1.2.1 圖存儲(chǔ)

一些圖數(shù)據(jù)庫(kù)使用 原生圖存儲(chǔ),這類存儲(chǔ)是經(jīng)過(guò)優(yōu)化的,并且是專門為了存儲(chǔ)和管理圖而設(shè)計(jì)的。并不是所有圖數(shù)據(jù)庫(kù)都是使用原生圖存儲(chǔ),也有一些圖數(shù)據(jù)庫(kù)將圖數(shù)據(jù)序列化,然后保存到關(guān)系型數(shù)據(jù)庫(kù)或者面向?qū)ο髷?shù)據(jù)庫(kù),或其他通用數(shù)據(jù)存儲(chǔ)中。

1.2.2 圖處理引擎

原生圖處理(也稱為 無(wú)索引鄰接)是處理圖數(shù)據(jù)的最有效方法,因?yàn)檫B接的節(jié)點(diǎn)在數(shù)據(jù)庫(kù)中物理地指向彼此。非本機(jī)圖處理使用其他方法來(lái)處理CRUD操作。

image-20220223183109256

比如:

  • Neo4J就是屬于原生圖數(shù)據(jù)庫(kù),它使用的后端存儲(chǔ)是專門為Neo4J這種圖數(shù)據(jù)庫(kù)定制和優(yōu)化的,理論上說(shuō)能更有利于發(fā)揮圖數(shù)據(jù)庫(kù)的性能。

  • AllegroGraph不是原生圖數(shù)據(jù)庫(kù),而將數(shù)據(jù)存儲(chǔ)在其他成熟的非圖后端系統(tǒng)上,比如Mysql或者Hbase。

1.3 應(yīng)用場(chǎng)景

世界上很多著名的公司都在使用圖數(shù)據(jù)庫(kù)。比如:

  • 社交領(lǐng)域:Facebook, Twitter,Linkedin用它來(lái)管理社交關(guān)系,實(shí)現(xiàn)好友推薦

  • 零售領(lǐng)域:eBay,沃爾瑪使用它實(shí)現(xiàn)商品實(shí)時(shí)推薦,給買家更好的購(gòu)物體驗(yàn)

  • 金融領(lǐng)域:摩根大通,花旗和瑞銀等銀行在用圖數(shù)據(jù)庫(kù)做風(fēng)控處理

  • 汽車制造領(lǐng)域:沃爾沃,戴姆勒和豐田等頂級(jí)汽車制造商依靠圖數(shù)據(jù)庫(kù)推動(dòng)創(chuàng)新制造解決方案

  • 電信領(lǐng)域:Verizon, Orange和AT&T 等電信公司依靠圖數(shù)據(jù)庫(kù)來(lái)管理網(wǎng)絡(luò),控制訪問(wèn)并支持客戶360

  • 酒店領(lǐng)域:萬(wàn)豪和雅高酒店等頂級(jí)酒店公司依使用圖數(shù)據(jù)庫(kù)來(lái)管理復(fù)雜且快速變化的庫(kù)存

2. 圖數(shù)據(jù) In NoSQL

NoSQL數(shù)據(jù)庫(kù)大致可以分為四類,而圖數(shù)據(jù)庫(kù)正是其一,各種圖數(shù)據(jù)庫(kù)對(duì)比,請(qǐng)見(jiàn)下方圖表。

img
分類 數(shù)據(jù)模型 優(yōu)勢(shì) 劣勢(shì) 舉例
鍵值數(shù)據(jù)庫(kù) 哈希表 查找速度快 數(shù)據(jù)無(wú)結(jié)構(gòu)化,通常只被當(dāng)作字符串或者二進(jìn)制數(shù)據(jù) Redis
列存儲(chǔ)數(shù)據(jù)庫(kù) 列式數(shù)據(jù)存儲(chǔ) 查找速度快;支持分布橫向擴(kuò)展;數(shù)據(jù)壓縮率高 功能相對(duì)受限 HBase
文檔型數(shù)據(jù)庫(kù) 鍵值對(duì)擴(kuò)展 數(shù)據(jù)結(jié)構(gòu)要求不嚴(yán)格;表結(jié)構(gòu)可變;不需要預(yù)先定義表結(jié)構(gòu) 查詢性能不高,缺乏統(tǒng)一的查詢語(yǔ)法 MongoDB
圖數(shù)據(jù)庫(kù) 節(jié)點(diǎn)和關(guān)系組成的圖 利用圖結(jié)構(gòu)相關(guān)算法(最短路徑、節(jié)點(diǎn)度關(guān)系查找等) 可能需要對(duì)整個(gè)圖做計(jì)算,不利于圖數(shù)據(jù)分布存儲(chǔ) Neo4j

3. 圖數(shù)據(jù)庫(kù) VS 關(guān)系型數(shù)據(jù)庫(kù)

與關(guān)系型數(shù)據(jù)庫(kù)和 NoSQL 數(shù)據(jù)庫(kù)相比,定義良好的圖數(shù)據(jù)庫(kù)都有著明顯優(yōu)勢(shì)。具體如下

  • 性能: 與關(guān)系型數(shù)據(jù)庫(kù)和NoSQL存儲(chǔ)處理關(guān)聯(lián)數(shù)據(jù)相比,選擇圖數(shù)據(jù)庫(kù)會(huì)有絕對(duì)的性能提升。隨著數(shù)據(jù)集的不斷增大,關(guān)系型數(shù)據(jù)庫(kù)處理密集join(join-intensive)查詢的性能也會(huì)隨之變差,而圖數(shù)據(jù)庫(kù)則不然。在數(shù)據(jù)集增大時(shí),它的性能趨向于保持不變,這是因?yàn)椴樵兛偸侵慌c圖的一部分相關(guān)。因此,每個(gè)查詢的執(zhí)行時(shí)間只和滿足查詢條件的那部分遍歷的圖的大?。ǘ皇钦麄€(gè)圖的大?。┏烧?。
  • 靈活: 圖天生就是可擴(kuò)展的,這意味著我們可以對(duì)一個(gè)已經(jīng)存在的結(jié)構(gòu)增加不同種類的聯(lián)系、新節(jié)點(diǎn)和新子圖,而不用擔(dān)心破壞已有的查詢或應(yīng)用程序的功能。這些特點(diǎn)對(duì)于開(kāi)發(fā)者的生產(chǎn)力和項(xiàng)目風(fēng)險(xiǎn)一般都有積極的意義。同時(shí)由于圖模型的靈活性,我們不必在項(xiàng)目最初就窮思竭慮地把領(lǐng)域中的每一個(gè)細(xì)枝末節(jié)都考慮到模型中—這種做法在不斷變化的業(yè)務(wù)需求面前,簡(jiǎn)直就是蠻干。圖的天然可擴(kuò)展性也意味著我們會(huì)做更少的數(shù)據(jù)遷移,從而降低維護(hù)開(kāi)銷和風(fēng)險(xiǎn)。
  • 敏捷性: 因?yàn)閳D數(shù)據(jù)庫(kù)不需要schema,所以它缺少以schema為導(dǎo)向的數(shù)據(jù)管理機(jī)制,即在關(guān)系世界中我們已經(jīng)熟知的機(jī)制。但這并不是一個(gè)風(fēng)險(xiǎn),相反,它促使我們采用了一種更可見(jiàn)的、可操作的管理方式。正如我們?cè)诘?章會(huì)講到的,圖數(shù)據(jù)庫(kù)的管理通常作用于編程方式,利用測(cè)試來(lái)驅(qū)動(dòng)數(shù)據(jù)模型和查詢,以及依靠圖來(lái)斷言業(yè)務(wù)規(guī)則。這不再是一個(gè)有爭(zhēng)議的做法,事實(shí)上這已經(jīng)比關(guān)系型開(kāi)發(fā)應(yīng)用更廣了。圖數(shù)據(jù)庫(kù)開(kāi)發(fā)方式非常符合當(dāng)今的敏捷軟件開(kāi)發(fā)和測(cè)試驅(qū)動(dòng)軟件開(kāi)發(fā)實(shí)踐,這使得以圖數(shù)據(jù)庫(kù)為后端的應(yīng)用程序可以跟上不斷變化的業(yè)務(wù)環(huán)境。

4. 關(guān)系查詢性能對(duì)比

在數(shù)據(jù)關(guān)系中心,圖形數(shù)據(jù)庫(kù)在查詢速度方面非常高效,即使對(duì)于深度和復(fù)雜的查詢也是如此。在《Neo4j in Action》這本書(shū)中,作者在關(guān)系型數(shù)據(jù)庫(kù)
和圖數(shù)據(jù)庫(kù)(Neo4j)之間進(jìn)行了實(shí)驗(yàn)。

img

他們的實(shí)驗(yàn)試圖在一個(gè)社交網(wǎng)絡(luò)里找到最大深度為5的朋友的朋友。他們的數(shù)據(jù)集包括100萬(wàn)人,每人約有50個(gè)朋友。實(shí)驗(yàn)結(jié)果如下:

深度 MySQL執(zhí)行時(shí)間(s) Neo4J執(zhí)行時(shí)間(s) 返回記錄數(shù)
2 0.016 0.01 ~2500
3 30.267 0.168 ~110 000
4 1543.505 1.359 ~600 000
5 未完成 2.132 ~800 000

在深度為2時(shí)(即朋友的朋友),兩種數(shù)據(jù)庫(kù)性能相差不是很明顯;深度為3時(shí)(即朋友的朋友的朋友),很明顯,關(guān)系型數(shù)據(jù)庫(kù)的響應(yīng)時(shí)間30s,已經(jīng)變得不可接受了;深度到4時(shí),關(guān)系數(shù)據(jù)庫(kù)需要近半個(gè)小時(shí)才能返回結(jié)果,使其無(wú)法應(yīng)用于在線系統(tǒng);深度到5時(shí),關(guān)系型數(shù)據(jù)庫(kù)已經(jīng)無(wú)法完成查詢。而對(duì)于圖數(shù)據(jù)庫(kù)Neo4J,深度從3到5,其響應(yīng)時(shí)間均在3秒以內(nèi)。

可以看出,對(duì)于圖數(shù)據(jù)庫(kù)來(lái)說(shuō),數(shù)據(jù)量越大,越復(fù)雜的關(guān)聯(lián)查詢,約有利于體現(xiàn)其優(yōu)勢(shì)。從深度為4/5的查詢結(jié)果我們可以看出,圖數(shù)據(jù)庫(kù)返回了整個(gè)社交網(wǎng)絡(luò)一半以上的人數(shù)。

5. 主流數(shù)據(jù)圖產(chǎn)品

根據(jù)DB-Engines最新發(fā)布的圖數(shù)據(jù)庫(kù)排名

image-20211209182201724
  1. Neo4j 業(yè)界老大,行業(yè)標(biāo)桿,江湖一哥;
  2. Nebula 異軍突起,厚積薄發(fā),當(dāng)紅新銳;

二者搜索熱度對(duì)比: https://db-engines.com/en/system/Nebula+Graph%3BNeo4j

image-20211208100202813

具體特性對(duì)比:

image-20211209182704013

對(duì)比總結(jié)

  1. 性能與成本:Neo4j開(kāi)源版本是單機(jī)的,最少2G內(nèi)存就可以支持億級(jí)別的數(shù)據(jù);Nebula性能突出但是維護(hù)成本較高,很吃資源(測(cè)試環(huán)境需要至少8G內(nèi)存才能啟動(dòng));
  2. 學(xué)習(xí)成本:Neo4j有專屬查詢語(yǔ)言“Cypher”,Nebula也有自己的“NQL”,二者都需要學(xué)習(xí)
  3. 開(kāi)發(fā)成本:Neo4j和Spring緊密合作,對(duì)于Java生態(tài)支持的更好;Nebula 在這方面剛剛起步

6. Cypher查詢語(yǔ)言

Cypher是Neo4j的圖形查詢語(yǔ)言,允許用戶存儲(chǔ)和檢索圖形數(shù)據(jù)庫(kù)中的數(shù)據(jù)。

比如下面我們直接通過(guò)代碼來(lái)對(duì)比下 MySQL 和 Neo4j 里面的查詢,我相信即使不寫(xiě)任何注釋,即使第一次接觸 Neo4j 的人也能輕輕松松的看懂這些查詢語(yǔ)句。

<!-- 1. 全表掃描 -->
<!-- mysql -->
SELECT p.*
FROM products as p;

<!-- neo4j -->
MATCH (p:Product)
RETURN p;


<!-- 2. 查詢價(jià)格最貴的10個(gè)商品,只返回商品名字和單價(jià) -->
<!-- mysql -->
SELECT p.ProductName, p.UnitPrice
FROM products as p
ORDER BY p.UnitPrice DESC
LIMIT 10;

<!-- neo4j -->
MATCH (p:Product)
RETURN p.productName, p.unitPrice
ORDER BY p.unitPrice DESC
LIMIT 10;


<!-- 3. 按照商品名字篩選 -->
<!-- mysql -->
SELECT p.ProductName, p.UnitPrice
FROM products AS p
WHERE p.ProductName = 'Chocolade';

<!-- neo4j -->
MATCH (p:Product)
WHERE p.productName = "Chocolade"
RETURN p.productName, p.unitPrice;

<!-- 其他的寫(xiě)法 -->
MATCH (p:Product {productName:"Chocolade"})
RETURN p.productName, p.unitPrice;

<!-- 4. 按照商品名字篩選2 -->
<!-- mysql -->
SELECT p.ProductName, p.UnitPrice
FROM products as p
WHERE p.ProductName IN ('Chocolade','Chai');

<!-- neo4j -->
MATCH (p:Product)
WHERE p.productName IN ['Chocolade','Chai']
RETURN p.productName, p.unitPrice;


<!-- 5. 模糊查詢和數(shù)值過(guò)濾 -->
<!-- mysql -->
SELECT p.ProductName, p.UnitPrice
FROM products AS p
WHERE p.ProductName LIKE 'C%' AND p.UnitPrice > 100;

<!-- neo4j -->
MATCH (p:Product)
WHERE p.productName STARTS WITH "C" AND p.unitPrice > 100
RETURN p.productName, p.unitPrice;


<!-- 6. 多表聯(lián)合查詢-->
<!-- mysql -->
SELECT DISTINCT c.CompanyName
FROM customers AS c
JOIN orders AS o ON (c.CustomerID = o.CustomerID)
JOIN order_details AS od ON (o.OrderID = od.OrderID)
JOIN products AS p ON (od.ProductID = p.ProductID)
WHERE p.ProductName = 'Chocolade';

<!-- neo4j -->
MATCH (p:Product {productName:"Chocolade"})<-[:PRODUCT]-(:Order)<-[:PURCHASED]-(c:Customer)
RETURN distinct c.companyName;


<!-- 7.  -->
<!-- mysql -->
SELECT e.EmployeeID, count(*) AS Count
FROM Employee AS e
JOIN Order AS o ON (o.EmployeeID = e.EmployeeID)
GROUP BY e.EmployeeID
ORDER BY Count DESC LIMIT 10;

<!-- neo4j -->
MATCH (:Order)<-[:SOLD]-(e:Employee)
RETURN e.name, count(*) AS cnt
ORDER BY cnt DESC LIMIT 10

下面在看一些更為復(fù)雜的例子,我們要查找Joe的所以二度好友:

image
MATCH
(person:Person)-[:KNOWS]-(friend:Person)-[:KNOWS]-
(foaf:Person)
WHERE
person.name = "Joe"
AND NOT (person)-[:KNOWS]-(foaf)
RETURN
foaf
// Joe認(rèn)識(shí)Sally,Sally認(rèn)識(shí)Anna。Bob被排除在結(jié)果之外,因?yàn)槌送ㄟ^(guò)Sally成為二級(jí)朋友之外,他還是一級(jí)朋友。

圖數(shù)據(jù)庫(kù)會(huì)經(jīng)常處理樹(shù)形結(jié)構(gòu)數(shù)據(jù),必須要遍歷Block樹(shù)的最大深度

   match (n:Block)
   where (n)-[:OWN]->() and not ()-[:OWN]->(n) // 找到根節(jié)點(diǎn)
   match p = (n)-[:OWN*1..]->(m) //查詢所有從根節(jié)點(diǎn)出發(fā)的路徑
   return p, length(p) as L
   order by L desc // 找到路徑長(zhǎng)度最大的
   limit 1

或者是要從固定節(jié)點(diǎn)(aid = 1000)向上尋找到另一個(gè)節(jié)點(diǎn)(aid=10)的最短路徑

match p = shortestPath( (e:block {aid:10000}) <-[*0..1000]- (r:block {aid:1}) ) 
return p;

更多cypher語(yǔ)法請(qǐng)閱讀官方文檔: Cypher語(yǔ)法

7. 總結(jié)

圖數(shù)據(jù)庫(kù)應(yīng)對(duì)的是當(dāng)今一個(gè)宏觀的商業(yè)世界的大趨勢(shì):憑借高度關(guān)聯(lián)、復(fù)雜的動(dòng)態(tài)數(shù)據(jù),獲得洞察力和競(jìng)爭(zhēng)優(yōu)勢(shì)。國(guó)內(nèi)越來(lái)越多的公司開(kāi)始進(jìn)入圖數(shù)據(jù)庫(kù)領(lǐng)域,研發(fā)自己的圖數(shù)據(jù)庫(kù)系統(tǒng)。對(duì)于任何達(dá)到一定規(guī)?;騼r(jià)值的數(shù)據(jù),圖數(shù)據(jù)庫(kù)都是呈現(xiàn)和查詢這些關(guān)系數(shù)據(jù)的最好方式。而理解和分析這些圖的能力將成為企業(yè)未來(lái)最核心的競(jìng)爭(zhēng)力。

更多學(xué)習(xí)資料:

  1. 如何使用Neoj4建模
  2. Cypher語(yǔ)法
  3. 深度運(yùn)算法 https://ramona-chen.top/2020/03/24/neo4j-cha-xun-duo-shen-du-guan-xi-jie-dian/
  4. Neo4j Java Driver https://neo4j.com/docs/developer-manual/current/drivers/get-started/
  5. Spring 實(shí)體映射關(guān)系 https://github.com/neo4j/neo4j-ogm
  6. 官方學(xué)習(xí)數(shù)據(jù) https://neo4j.com/graphgists/
  7. 運(yùn)維 Shell 腳本命令 https://neo4j.com/docs/operations-manual/4.3/tools/cypher-shell/
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容