圖數據庫 - 維基百科:在計算機科學中, 圖數據庫(英語:graph database, GDB)是一個使用圖結構進行 語義查詢的 數據庫,它使用 節點、 邊和屬性來表示和存儲數據。該系統的關鍵概念是 圖,它直接將存儲中的數據項,與數據 節點和節點間表示關係的 邊的集合相關聯。這些關係容許直接將存儲區中的數據連接在一塊兒,而且在許多狀況下,能夠經過一個操做進行檢索。圖數據庫將數據之間的關係做爲優先級。查詢圖數據庫中的關係很快,由於它們永久存儲在數據庫自己中。可使用圖數據庫直觀地顯示關係,使其對於高度互連的數據很是有用。
圖數據庫是一種 非關係型數據庫,以解決現有 關係數據庫的侷限性。圖模型明確地列出了數據節點之間的依賴關係,而關係模型和其餘 NoSQL 數據庫模型則經過隱式鏈接來連接數據。圖數據庫從設計上,就是能夠簡單快速地檢索難以在關係系統中建模的複雜層次結構的。圖數據庫與 20 世紀 70 年代的網絡模型數據庫類似,它們都表示通常的圖,可是網絡模型數據庫在較低的抽象層次上運行,而且不能輕鬆遍歷一系列邊。
圖數據庫的底層存儲機制可能各有不一樣。有些依賴於關係引擎並將圖數據「存儲」到表中(雖然表是一個邏輯元素,可是這種方法在圖數據庫、圖數據庫管理系統和實際存儲數據的物理設備之間施加了另外一層抽象)。另外一些則使用 鍵值存儲或 面向文檔的數據庫進行存儲,使它們具備固有的 NoSQL 結構。大多數基於非關係存儲引擎的圖數據庫還添加了 標記或 屬性的概念,這些標記或屬性本質上是具備指向另外一個文檔的指針的關係。這樣就能夠對數據元素進行分類,以便於集中檢索。
從圖數據庫中檢索數據須要 SQL 以外的 查詢語言,SQL是爲了處理關係系統中的數據而設計的,所以沒法「優雅地」處理遍歷圖。截至 2017 年,沒有一個像 SQL 那樣通用的圖查詢語言,一般都是僅限與一個產品的。不過,已經有一些標準化的工做,使得 Gremlin、 SPARQL 和 Cypher 成爲了多供應商查詢語言。除了具備查詢語言接口外,還能夠經過應用程序接口(API)訪問一些圖數據庫。圖數據庫與圖計算引擎不一樣。圖數據庫是轉換關係 OLTP 數據庫的技術。而圖計算引擎在 OLAP 中用於批量分析。因爲主要技術公司在使用專有圖數據庫方面的成功以及開源圖數據庫的引入,圖數據庫在 2000 年代引發了至關大的關注。php
上面部分引用了維基百科對圖數據庫的詞條來說解何爲圖數據庫,而本文整理於圖數據庫 Nebula Graph 交流羣中對圖數據庫的零碎知識,做爲對圖數據庫知識的補充。本文分爲小知識及 Q&A 兩部分。前端
小知識算法
Q&A 提問回答數據庫
學習圖數據庫的起手式——瞭解圖數據庫興起的契機。編程
2010 年先後,對於社交媒體網絡研究的興起帶動了圖計算的大規模應用。後端
2000 年先後熱門的是 信息檢索
和 分析
,主要是 Google 的帶動,以及 Amazon 的 e-commerce 所用的協同過濾推薦,當時 collaborative filtering也被認爲是 information retrieval 的一個細分領域,包括 Google 的 PageRank 也是在信息檢索領域研究較多。後來纔是 Twitter,Facebook 的崛起帶動了網絡科學 Network science的研究。設計模式
圖理論和圖算法不是新科學,很早就有,只是最近 20 年大數據,網絡零售和社交網絡的發展, big data
、social networks
、e-commerce
、Web 2.0
讓圖計算有了新的用武之地,並且硬件計算力的提升和分佈式計算日益成熟的支持也使圖計算在高效處理海量數據成爲可能。瀏覽器
學習完圖數據庫發展的契機,咱們來學習下圖數據庫存儲方式和一種圖數據庫存儲層的設計探討。網絡
Bruceleexiaokan:基於內存的圖數據庫有其優點,特別對於 大規模深度遍歷
以及基於之上的 graph model 計算
,這在大規模並行處理( MPP )是有較強優點,其訪問語言更像是編程語言而並不是圖遍歷。架構
Sherman:各類存儲各有優缺點,各有擅長的應用場景,因此離開了場景和需求,很難對比不一樣的解決方案。
Bruceleexiaokan:基於分佈式 kv 之上的圖數據庫,對於大規模深度遍歷和計算,對於graph model 的支持,有其缺陷。圖數據庫須要有分類,咱們須要明白討論的是哪種。
若是講到第 3 種,圖結構基於內存的方案有優點。第 1 和 2 種大規模圖數據庫主要也就是基於 kv+ 索引
無中心化的存儲集羣,通常單個集羣仍是有必定的大小限制,不宜過大。存儲層的抽象在於,數據集(圖的話就是不一樣的點和邊)到存儲集羣的邏輯映射對用戶透明,用戶可用性要求高的場景須要考慮雙集羣互爲災備。單集羣的數據平衡是集羣內部的事,集羣和集羣間的數據平衡是須要設計的,其中線下到線上的數據傳輸通道尤爲重要。
設計原則:
學習完存儲和設計的小知識,來對比下圖數據庫圖結構的可視化和 GIS 數據的可視化。
關於圖結構可視化與 GIS 數據的可視化本質上有比較大的差別:
GIS 是 Hierarchical + 瓦片式
貼片展現的,而圖結構自己是 flat 的,只能一次性將全部 touch 到的數據所有展現出來。可是 GIS 的作法能夠給咱們啓示,結合具體的業務場景,可否也作一個 層級抽樣
,可是圖抽樣的問題是:如何在抽樣的同時,儘可能 保留子圖的連通性
(不然可能 high level 的層顯示的都是孤立的點,只有最後最細粒度的層纔會顯示全部數據)。
一些粗淺的想法:能夠結合圖計算的技術,先算連通子圖,而後在連通子圖內部算 PageRank,按照 PageRank 大小劃分紅不一樣的區間,至關於按照 PageRank 值作 Hierarchical 分層,在層次切換時,爲了保證圖的連通性,除了顯示下一個層次的頂點(PageRank 值在下一個區間)以外,還須要顯示這 2 個層次抽樣出來的頂點的邊(這至關於一個子圖內部的連通路徑的檢索,若是能作 aggreate 更好,若是這些邊不少,是否能夠按照 EdgeType aggregate,先顯示統計值,若是用戶有興趣再展開——即圖數據庫返回 aggregation 值,前端生成」虛擬」的邊,隨着進一步展開,這些」虛擬的邊」會被實際明細邊取代)。
上述 trick 只是爲了解決圖數據像 GIS 同樣平滑展現的問題,缺點也比較明顯,Hierarchical 抽樣代價高。
另外,圖數據的展現問題,不是一個獨立的前端技術問題,還涉及到後端圖數據庫以下 feature 的支持:
內置一些 AP 性算法,如 PageRank、lpa、環探測等。
圖數據可視化,還須要考慮:
前端數據承載量是有限的,CS 類型的可視化工具還好點,BS 類型的可視化工具,瀏覽器承載的量就更少。如何在業務上將 touch 到的數據量限制在必定範圍內是應用是要考慮的。
此外,因爲頂點和邊的 name 和其餘 tag 信息,通常在可視化的時候不會一次性都顯示在圖上,首次繪製可僅向圖數據庫請求 name,後續 tag 的 properties 在用戶感興趣的時候(點擊/hover)時再次請求。
佈局問題:目前常見的無非是力導引、圓形、樹形、網格型,這些都是無任何業務語義的佈局,如樹形佈局,哪些應該做爲頂層節點,哪些是下一級節點,若是僅僅經過邊的有向性,單個 EdgeType 顯示還好,多個 EdgeType 混合在一棵樹上顯示的時候會破壞掉單個 EdgeType 樹的結構,必須引入業務規則來限制不一樣佈局下的問題
因爲 Q&A 整理於 Nebula Graph 交流羣,有多人蔘與討論,因此如下問題回覆中會有羣友暱稱出現,不作 Nebula Graph 官方成員和羣友身份區分,僅交流圖數據庫技術~若是你對下列問題有不一樣的見解歡迎本文評論區交流(≧▽≦),加入圖數據庫交流羣請加 WeChat:NebulaGraphbot
提問:計算存儲分離的話,數據遷移,請問下大佬們,網絡帶寬會是瓶頸嗎?Nebula 怎麼解決的呀?
恆子:如今都萬兆網卡了,通常機房內很難把帶寬打滿的,一般 IO 會先是瓶頸。
波娃子:若是是地理分佈式的圖數據庫,帶寬是要考慮的性能限制因素。
Sherman:是的,如今比較流行的作法是兩地三中心或者三地五中心。分佈式圖數據庫,既有圖的部分,也必然會涉及到分佈系統的部分
Bruceleexiaokan:因爲大規模在線圖數據庫都設計成計算和存儲分離,數據存儲的設計是尤其重要。就金融 Risk 而言,邏輯上其實就是一張大圖,有上百 TB 的數據量,可線性擴展的存儲層設計是圖數據庫的關鍵
提問:爲何都設計成計算存儲分離的模式,有什麼重要的考量嗎
Bruceleexiaokan:對於 Risk 而言,在線是 inference 爲主,大部分場景是爲了 feature 計算,基本在 2-3 跳之內的圖遍歷,都很簡單,可是對於性能和可用性的要求很高,因此在線圖數據庫存儲分離很合理。但針對數據分析的圖數據庫,其設計會不同,更須要的是圖的深度遍歷能力,所以存儲分離應該是個問題,但如何支持大規模的圖,如何 scale up 應該是關鍵,而不是 scale out。
天師:存儲計算分離大可能是適應雲計算架構:存儲層買空間,計算層買彈性虛機。
吳敏:長期看,計算、存儲和網絡幾個硬件模塊發展的速度是不太同樣的,並不都是摩爾定理的速度,分離能更合適長期硬件演進
Sherman:我以爲存儲計算分離的一個很大的好處是存儲集羣和計算集羣能夠獨立擴縮容,能夠經過對不一樣集羣容量的調整,最終達到可以知足業務需求的最佳搭配。
提問:怎麼理解 Vertex 和 Tag 之間的關係,Schema 裏面有沒有 Vertex 的概念?一個頂點 ID 能夠對應多個 Tag 是這個意思嗎?
Sherman:解釋一下 Vertex,Tag,Edge 以及他們之間的關係:
Vertex 是一個頂點,用一個 64 位的 ID 來標識,一個 Vertex 能夠被打上多個 Tag(標籤),每一個 Tag 定義了一組屬性。
舉個例子,咱們能夠有 Person 和 Developer 這兩個 Tag,Person 這個 Tag 裏定義了姓名、電話、住址等等信息,Developer 這個 Tag 裏可能定義了熟悉的編程語言、工做年限、GitHub 帳號等等信息。一個 Vertex 能夠被打上 Person 這個 Tag,這就表示這個 Vertex 表明了一個 Person,同時也包含了 Person 裏的屬性。另外一個 Vertex 可能被同時打上了 Person 和 Developer 這兩個 Tag,那就表示這個 Vertex 不只是一個 Person,仍是一個 Developer。
Sherman:Vertex 和 Vertex 之間能夠用 Edge 相連,每一條 Edge 都會有類型,好比是好友關係。每一個 Edge Type 也能夠定義一組屬性。Edge 通常用來表示一種關係,或者一個動做。好比,Peraon A 給 Person B 轉了一筆錢,那 A 和 B 之間就會有一條 transfer 類型的邊,transfer 這個邊類型(Edge Type)能夠定義一組屬性,好比轉帳金額,轉帳時間等等。
Sherman:任何兩個 Vertex 之間能夠有多種類型的邊,也能夠有多條同種類型的邊,好比轉帳,兩個 Person 之間能夠有多筆轉帳,那麼每筆轉帳就是一條邊。
提問:對於例子有一個小小疑問,這裏的 Tag 能夠理解爲本體 ontology 嗎?
Sherman:按個人理解,ontology 應該是整張知識圖譜,也就是說包含 Vertex 和 Edge。在 Nebula 裏,Vertex 自己不含內容(也就是說沒有屬性),內容是存放在 Tag 裏的,這裏「內容」指的是 ontology 裏的concept,「邊」就是 ontology 裏的 relationship。
提問:追加個問題: 多個標籤是否支持層級關係,好比組織架構什麼的?謝謝?
在 Nebula 裏,能夠定義標籤之間的依賴關係,好比上面的例子裏,Developer 依賴 Person。
提問:若是要構建一個網絡,用戶,商家,公衆號,文章,這些 ID 會重複衝突的。根據如今 vertex id就能夠惟一指代點的原則,原有的 ID 不能直接使用,有什麼辦法構建出這個網絡嗎?仍是把 ID 做爲Tag屬性,而後建索引。
吳敏:類型和原始 ID 拼在一塊兒 hash,做爲 VID,而後把原始 ID 做爲一個 property。
Sherman:因爲業務變幻無窮,因此當初咱們決定把如何產生 VID 交個業務來決定。VID 是一個 64 位整數,在你的 case 裏,若是 ID 不足 64 位,那就能夠用 2-4 bit 來表示不一樣的類型,這樣就把原來可能衝突的 ID 分到了不一樣的空間。若是原來的 ID 已是 64 bit 的了,那能夠像@吳敏 說的那樣作 hash,把真實 ID 保存在屬性裏
提問:大佬們,咱們想了解下 Nebula Graph 和 Tiger Graph有關係,兩者有什麼區別麼
Sherman:簡單的講,Tiger Graph 不是真正意義上的對等分佈式,它是有中心節點的分佈式,它分佈存儲的是點和邊上的屬性,可是整張圖的關係必須保存在一臺機器上。同時在運行的時候,整張圖必須加載到內存裏,這就限制了它能處理的圖的規模。而一個產品的架構一旦創建以後,要改動不是一件容易的事情,基本至關於重作。
J.GUARDIAN:簡單理解的話,Tiger Graph 爲了性能犧牲了圖規模的處理能力,而 Nebula 解決的圖規模的能力,可是相對會稍微犧牲一些性能。
Sherman:也不徹底是,固然這是我以前對 Tiger Graph 的瞭解。
提問: 我看咱們的文檔裏寫着「一個頂點必須至少有一個類型的標籤」,可是我注意到 Neo4j 是支持 0 個標籤的,請問沒有標籤的節點在查詢時跟普通標籤用法同樣麼,爲何要支持 0 個標籤呢?這樣作有什麼意義呢?
Sherman:多數的圖計算性能評測的數據集(如 Graph500、Twitter)都是 0 標籤,也就是無屬性過濾條件。這樣能看出一個圖引擎的最核心的性能。經過標籤過濾在大多數狀況下對圖進行動態剪枝,時耗進而兒會縮短。
提問:你們怎麼看「圖數據庫要有索引」這個問題?
Bruceleexiaokan:最終這是一個設計上的trade off
問題,不一樣數據分佈和不一樣訪問需求對於不一樣的設計方案,性能確定是不一樣的。最好的方案是設計存儲訪問抽象,保留設計和實現靈活性,針對不一樣場景能夠有不一樣優化。
相鄰邊的索引和節點 inline 存儲本是一種優化,能夠減小物理磁盤 block read 數量,和節點一塊讀和寫。但到了一些特殊場景:
Sherman:@Bruceleexiaokan 徹底贊成,索引的使用要看場景,過分使用索引會得不償失。
提問:Nebula 是對臨接點有索引的 對吧
Sherman:對屬性有索引
提問:咱們知識圖譜業務場景,查節點間的路徑,請問下實時計算結果的效率怎麼樣呀?仍是說比較推薦離線計算?Nebula 是存儲計算分離的是吧?
Sherman:說一下我的理解,我以爲知識圖譜的場景通常是須要在線查詢的,由於不知道會有怎麼樣的查詢問題。嗯,是的,Nebula 是存儲計算分離的,最好的好處是部署方式靈活,計算節點和存儲節點能夠根據不一樣的需求獨立擴縮容。
提問:各副本之間是最終一致嗎?仍是強一致呀?
吳敏:各副本之間是基於 Raft 協議的強一致。
圖數據庫 Nebula Graph Beta 版本上線,版本 捉蟲活動 正在進行歡迎來找 Bug 😁