天天看點

公司讓我調研系列-圖資料庫Nebula

公司讓我調研下圖資料庫,本文是對Nebula官方教程和社群實踐的的一個整理.

中間發生了一個趣事,

在某一個微信群,談到了圖資料時,得到的回答是

公司讓我調研系列-圖資料庫Nebula

圖是什麼

圖論始于 18 世紀初期的柯尼斯堡七橋問題。柯尼斯堡當時是普魯士的城市,普雷格爾河穿過柯尼斯堡,不僅把柯尼斯堡分成了兩部分,而且還在河中間形成了兩個小島。這就将整個城市分割成了四個區域,各區域由七座橋連接配接。在所有的橋都隻能走一遍的前提下,如何能把這個地方所有的橋都走一遍呢?

公司讓我調研系列-圖資料庫Nebula

歐拉發表的相關論文被認為是圖論領域的第一篇文章,是以普遍認為歐拉是圖論的創始人。

一張圖由一些小圓點(稱為頂點或節點,即 Vertex)和連接配接這些圓點的直線或曲線(稱為邊,即 Edge)組成。

公司讓我調研系列-圖資料庫Nebula
  • 節點,即對象或實體。通常簡稱為點(Vertex)。
  • 節點之間的關系,通常簡稱為邊(Edge)。通常邊是有方向或者無方向的,以表示兩個實體之間有持續的關系。

股權關系

公司讓我調研系列-圖資料庫Nebula

點通常是一個自然人或者是一家企業,邊通常是某自然人與某企業之間的股權關系。

點上的屬性可以是自然人姓名、年齡、身份證号等。邊上的屬性可以是投資金額、投資時間、董監高等職位關系。

權力的遊戲

公司讓我調研系列-圖資料庫Nebula

點為人物,邊為人物之間的互動關系;點的屬性為人物姓名、年齡、陣營等,邊的屬性(距離)為兩個人物之間的互動次數,互動越頻繁距離越近。

黑産關系分析

公司讓我調研系列-圖資料庫Nebula
公司讓我調研系列-圖資料庫Nebula

在一個黑産賬戶和裝置網絡中,其中的點可以是賬戶、手機裝置和 WIFI 網絡,邊是這些賬戶與手機裝置之間的登入關系,以及手機裝置和 WIFI 網絡之間的接入關系。

這些登入記錄的網絡構成了黑産群體網絡的團夥作案特征。360 數科、快手、微信、知乎、攜程金融這些公司都通過圖技術實時(毫秒級的)識别超過百萬個的黑産社群。

推薦系統

地理位置與圖的結合也可以用于一些 O2O 的場景,例如基于 POI(Point-of-Interest)的實時美食推薦,使得美團這類本地生活服務平台公司能在消費者在打開 APP 的時候,實時推薦出更為合适的商家。

公司讓我調研系列-圖資料庫Nebula

使用範圍總結

欺詐檢測

金融機構必須仔細研究大量的交易資訊,才能檢測出潛在的金融欺詐行為,并了解某個欺詐行為和裝置的内在關聯。這種場景可以通過圖來模組化,然後借助 NebulaGraph,可以很容易地檢測出詐騙團夥或其他複雜詐騙行為。

推薦系統

NebulaGraph 能夠及時處理通路者産生的實時資訊,并且精準推送文章、視訊、産品和服務。

知識圖譜

自然語言可以轉化為知識圖譜,存儲在 NebulaGraph 中。用自然語言組織的問題可以通過智能問答系統中的語義解析器進行解析并重新組織,然後從知識圖譜中檢索出問題的可能答案,提供給提問人。

社交網絡

人際關系資訊是典型的圖資料,NebulaGraph 可以輕松處理數十億人和數萬億人際關系的社交網絡資訊,并在海量并發的情況下,提供快速的好友推薦和工作崗位查詢。

為什麼要使用圖資料庫

雖然關系型資料庫與 XML/JSON 等半結構類型的資料庫,都可以用來描述圖結構的資料模型,但是,圖(資料庫)不僅可以描述圖結構與存儲資料本身,更着眼于處理資料之間的關聯(拓撲)關系.

優點包括以下:

  1. 圖是一種更直覺、更符合人腦思考直覺的知識表示方式。這使得我們在抽象業務問題時,可以着眼于“業務問題本身”,而不是“如何将問題描述為資料庫的某種特定結構(例如表格結構)”。
  2. 圖更容易展現資料的特征,例如轉賬的路徑、近鄰的社群
  3. 圖查詢語言是針對圖結構通路設計的,可以更加直覺。
  4. 由于存儲引擎和查詢引擎可以針對圖的結構專門設計,圖的周遊(對應 SQL 中的 join)要高效得多。
  5. 圖資料庫具有廣泛的适用場景。例如資料內建(知識圖譜)、個性化推薦、欺詐與威脅檢測、風險分析與合規、身份(與控制權)驗證、IT 基礎設施管理、供應鍊與物流、社交網絡研究等。
  6. 圖資料庫用圖來存儲資料,而圖是最接近高度靈活、高性能的資料結構之一
  7. 圖資料庫是一種專門用于存儲和檢索龐大資訊網的存儲引擎,它能夠高效地将資料存儲為點和邊,并允許對這些點邊結構進行高性能的檢索和查詢。

與比較PostgreSQL

要求:查找某人(Person)在社交網絡上釋出的文章(Posts);查找相應的回複(Message,回複本身還會被多次回複);發帖時間、回帖時間都滿足一定條件;根據回帖數量對結果排序。

公司讓我調研系列-圖資料庫Nebula
WITH RECURSIVE post_all(psa_threadid
                      , psa_thread_creatorid, psa_messageid
                      , psa_creationdate, psa_messagetype
                       ) AS (
    SELECT m_messageid AS psa_threadid
         , m_creatorid AS psa_thread_creatorid
         , m_messageid AS psa_messageid
         , m_creationdate, 'Post'
      FROM message
     WHERE  m_c_replyof IS NULL -- post, not comment
       AND m_creationdate BETWEEN :startDate AND :endDate
  UNION ALL
    SELECT psa.psa_threadid AS psa_threadid
         , psa.psa_thread_creatorid AS psa_thread_creatorid
         , m_messageid, m_creationdate, 'Comment'
      FROM message p, post_all psa
     WHERE  p.m_c_replyof = psa.psa_messageid
     AND m_creationdate BETWEEN :startDate AND :endDate
)
SELECT p.p_personid AS "person.id"
     , p.p_firstname AS "person.firstName"
     , p.p_lastname AS "person.lastName"
     , count(DISTINCT psa.psa_threadid) AS threadCount
END) AS messageCount
     , count(DISTINCT psa.psa_messageid) AS messageCount
  FROM person p left join post_all psa on (
        p.p_personid = psa.psa_thread_creatorid
   AND psa_creationdate BETWEEN :startDate AND :endDate
   )
 GROUP BY p.p_personid, p.p_firstname, p.p_lastname
 ORDER BY messageCount DESC, p.p_personid
 LIMIT 100;           

如果使用為圖專門設計的圖語言 Cypher 編寫查詢語句:

MATCH (person:Person)<-[:HAS_CREATOR]-(post:Post)<-[:REPLY_OF*0..]-(reply:Message)
WHERE post.creationDate >= $startDate AND post.creationDate <= $endDate
  AND reply.creationDate >= $startDate AND reply.creationDate <= $endDate
RETURN
  person.id, person.firstName, person.lastName, count(DISTINCT post) AS threadCount,
  count(DISTINCT reply) AS messageCount
ORDER BY
  messageCount DESC, person.id ASC
LIMIT 100           

效率比較

由于存儲引擎和查詢引擎可以針對圖的結構專門設計,圖的周遊(對應 SQL 中的 join)要高效得多。下圖是知名産品 Neo4j 所做的一個對比。

公司讓我調研系列-圖資料庫Nebula

圖資料庫

  • 第一代圖資料庫的先行者 Neo4j
  • 第二代(分布式)圖資料庫:Titan 和其後繼者 JanusGraph
  • 同期知名産品 OrientDB, TigerGraph, ArangoDB, 和 DGraph
  • 新一代開源分布式圖資料庫 NebulaGraph

最佳實踐分享案例

推薦場景

推薦基本都是基于使用者喜好、物品的特征、使用者與物品互動曆史和其他相關上下文去做的。

一個推薦系統會包含以下幾個部分:

資料、特征的處理

從特征出發,生成推薦清單

過濾、排序推薦清單

這其中,過濾的核心方法主要有兩種:基于内容的過濾 Content-Based Filtering、與協同過濾 Collaborative Filtering

CBF,内容過濾的思想是利用領域知識、曆史記錄、中繼資料分别對使用者和物件做畫像、打标簽,最終根據使用者的标簽與待推薦物件之間的距離評分進行排序給出相關推薦。

協同過濾主要可以分為兩種:

User-User CF 基于多個使用者對物件的曆史行為,判定使用者之間的相似性,再根據相似使用者的選擇推薦新的物件;

Item-Item CF 判斷物件之間的相似性,給使用者推薦他喜歡的物品相似的物品。

ItemCF 看起來和前邊的 CBF 有些類似,核心差別在于 CBF 找到相似物件的方式是基于物件的“内容”本身,是領域知識的畫像,而 ItemCF 的協同則是考慮使用者對物件的曆史行為。

https://discuss.nebula-graph.com.cn/t/topic/11491

風控場景

風控場景中使用到很多圖挖掘算法,如:

高密度子圖,一些異常賬号和異常行為對象之間會存在高密度子圖。

鄰居域異常,異常節點、邊、網絡存在異常的形狀(如星形散射狀),即該賬戶的鄰居域異常。

複雜網絡,比如異常網絡的度分布和正常網絡的度分布是不同的。如有時挖掘了一些團夥,可以基于 Degree Sequence 建構特征和模型。不同 Degree Sequence 分布的網絡存在不同的特性,這可以指導我們進一步建構拓撲相關特征。

https://discuss.nebula-graph.com.cn/t/topic/11705

DEMO操作

環境請自行搭建哦,增删改查四件套

公司讓我調研系列-圖資料庫Nebula
CREATE SPACE basketballplayer(partition_num=15, replica_factor=1, vid_type=fixed_string(30));
USE basketballplayer;
CREATE TAG player(name string, age int);
CREATE TAG team(name string);
CREATE EDGE follow(degree int);
CREATE EDGE serve(start_year int, end_year int);
INSERT VERTEX player(name, age) VALUES "player100":("Tim Duncan", 42);
INSERT VERTEX player(name, age) VALUES "player101":("Tony Parker", 36);
INSERT VERTEX player(name, age) VALUES "player102":("LaMarcus Aldridge", 33);
INSERT VERTEX team(name) VALUES "team203":("Trail Blazers"), "team204":("Spurs");
INSERT EDGE follow(degree) VALUES "player101" -> "player100":(95);
INSERT EDGE follow(degree) VALUES "player101" -> "player102":(90);
INSERT EDGE follow(degree) VALUES "player102" -> "player100":(75);
INSERT EDGE serve(start_year, end_year) VALUES "player101" -> "team204":(1999, 2018),"player102" -> "team203":(2006,  2015);
//從 VID 為player101的球員開始,沿着邊follow找到連接配接的球員。
GO FROM "player101" OVER follow YIELD id($);
//從 VID 為player101的球員開始,沿着邊follow查找年齡大于或等于 35 歲的球員,
//并傳回他們的姓名和年齡,同時重命名對應的列。
GO FROM "player101" OVER follow WHERE properties($).age >= 35 
        YIELD properties($).name AS Teammate, properties($).age AS Age;




從 VID 為player101的球員開始,沿着邊follow查找連接配接的球員,然後檢索這些球員的球隊。為了合并這兩個查詢請求,可以使用管道符或臨時變量。
GO FROM "player101" OVER follow YIELD dst(edge) AS id | 
        GO FROM $-.id OVER serve YIELD properties($).name AS Team, 
        properties($^).name AS Player;
//查詢 VID 為player100的球員的屬性。
FETCH PROP ON player "player100" YIELD properties(vertex);
//用UPDATE修改 VID 為player100的球員的name屬性,然後用FETCH語句檢查結果。
UPDATE VERTEX "player100" SET player.name = "Tim";
FETCH PROP ON player "player100" YIELD properties(vertex);
//用UPDATE修改某條邊的degree屬性,然後用FETCH檢查結果。
UPDATE EDGE ON follow "player101" -> "player100" SET degree = 96;
FETCH PROP ON follow "player101" -> "player100" YIELD properties(edge);




//用INSERT插入一個 VID 為player111的點,然後用UPSERT更新它。
INSERT VERTEX player(name,age) VALUES "player111":("David West", 38);
UPSERT VERTEX "player111" SET player.name = "David", player.age = $^.player.age + 11 
        WHEN $^.player.name == "David West" AND $^.player.age > 20 
        YIELD $^.player.name AS Name, $^.player.age AS Age;




//删點.邊
DELETE VERTEX "player111", "team203";
DELETE EDGE follow "player101" -> "team204";




//建立索引
CREATE TAG INDEX IF NOT EXISTS player_index_1 ON player(name(20));
//確定生效
REBUILD TAG INDEX player_index_1
//使用 LOOKUP 語句檢索點的屬性。
LOOKUP ON player WHERE player.name == "Tony Parker" 
        YIELD properties(vertex).name AS name, properties(vertex).age AS age;           

nGql

nGQL(NebulaGraph Query Language)是 NebulaGraph 使用的的聲明式圖查詢語言,支援靈活高效的圖模式,而且 nGQL 是為開發和運維人員設計的類 SQL 查詢語言,易于學習。

https://docs.nebula-graph.com.cn/3.4.1/3.ngql-guide/1.nGQL-overview/1.overview/

總結

圖資料庫可以極大的助力資料分析場景,

圖資料庫善于處理大量的、複雜的、互聯的、多變的網狀資料.

傳統的關系型資料庫,在處理複雜資料關系上表現得不是很完美。

如果對您有幫助,請關注一下這個二流程式員的公衆号搜尋-> 進階面試工程師,謝謝!

繼續閱讀