圖數據庫 | 24、如何進行正確性驗證?

圖數據庫計算和查詢結果的正確性,這個重要性當然是不言而喻的!

老夫之前也寫文章講過,今天再手書一篇,旨在向大家系統地介紹一下圖數據庫查詢與計算到底如何進行正確性驗證!!!

圖數據庫中的操作分為以下2類:

·?面向元數據的操作:即面向頂點、邊或它們之上的屬性字段的操作,具體可以分為增、刪、改、查4類。

·??面向高維數據的操作:這也是本書關注的重點,例如面向全圖或子圖數據的查詢結果返回多個頂點、邊組合而成的高維數據結構,可能是多頂點的集合、點邊構成的路徑、子圖(子網)甚至是全圖遍歷結果。

面向高維數據的查詢有以下3類:

·?K鄰查詢:即返回某頂點的全部K度(跳)鄰居頂點集合。K鄰查詢可以有很多變種,包括按照某個特定方向、點邊屬性字段進行過濾。還有全圖K鄰查詢,也被視作一種高計算復雜度的圖算法。

·?路徑查詢:常見的有最短路徑、模板路徑、環路路徑、組網查詢、自動展開查詢等。

·?圖算法:圖算法在本質上是面向元數據、K鄰、路徑等查詢方式的組合。

無論以何種方式進行高維查詢,圖數據庫中的操作無外乎遵循如下3種遍歷模式:

·?廣度優先:如K鄰查詢、最短路徑等。·深度優先:如環路查詢、組網查詢、模板路徑查詢、圖嵌入隨機游走等。

·?深度優先與廣度優先兼而有之:以最短路徑方式遍歷的模板路徑或組網查詢、帶方向或條件過濾的模板K鄰查詢、定制化的圖算法等。

注意:
面向元數據的圖數據庫操作和關系型數據庫有相似的地方,正確性驗證方法在此就不再贅述了。本文老夫著重介紹圖數據庫特有的高維數據查詢正確性驗證。

我們以圖數據庫基準性能評測中常用的Twitter-2010數據集為例來說明如何進行圖查詢的正確性驗證。

Twitter數據集(其中頂點數量為4200萬,邊數量為14.7億,原始數據占24.6GB)的下載鏈接為:http://an.kaist.ac.kr/traces/WWW2010.html。

在開始驗證前,以Twitter數據集為例,了解一下圖數據模型的特征。

(1)有向圖

由頂點(人)和邊(關注關系)組成,其中關注關系為有向邊。

Twitter源數據中有兩列,對應每一行是由Tab鍵分隔的兩個數字,例如12與13,代表兩個用戶的ID,表示兩者間的有向的關注關系:12關注13。在圖數據建模中應該構建為兩條邊,一條表示從12到13的正向邊,另一條則是從13到12的反向邊,缺一不可。后面的驗證細節中很多正確性的問題都與此相關——沒有構建反向邊,查詢結果不可避免會出錯。

(2)簡單圖與多邊圖

如果一對頂點間存在超過(含)2條邊,則其為多邊圖,否則為簡單圖。

在簡單圖中任意頂點間最多只有1條邊,因此簡單圖也稱作“單邊圖”?。

Twitter數據實際上是一種特殊的多邊圖,當兩個用戶互相關注對方時,他們之間可以形成兩條邊。在金融場景中,如果用戶賬戶為頂點,轉賬交易為邊,那么兩個賬戶之間可以存在多筆轉賬關系,即多條邊。

很多系統只能支持簡單的單邊圖,這樣就會帶來很多圖上查詢與計算的結果錯誤的問題。

(3)點、邊屬性

Twitter數據本身除了隱含的邊的方向可以作為一種特殊的邊屬性外,并不存在其他點邊屬性。這個特征區別于金融行業中的交易流水圖——無論是頂點還是邊都可能存在多個屬性,可以被用來對實體或關系進行精準的查詢過濾、篩選、排序、聚合運算、下鉆、歸因分析等。不支持點邊屬性過濾的圖數據庫可以認為功能沒有實現閉環,也不具備商業化價值。

我們以K鄰查詢為例來驗證圖數據庫查詢結果的正確性!!

首先,我們要明確K鄰查詢的定義,事實上K-Hop查詢有兩種含義,分別是:第K度(跳)鄰居、從第1跳到第K跳的全部鄰居。

其中第K跳鄰居指的是全部距離原點最短路徑距離為K的鄰居數量。這兩種含義的區別僅僅在于到底K-Hop的鄰居是只包含當前步幅(跳、層)的鄰居,還是包含前面所有層的鄰居。無論是哪種定義,有兩個要點直接影響“正確性”?:

·?K鄰查詢的正確實現方式默認應基于廣度優先搜索。

·?結果集去重:即第K層的鄰居集合中不會有重復的頂點,也不會有在其他層出現的鄰居(已知的多款圖數據庫系統都存在數據結果沒有去重的錯誤)?。

有的圖數據庫(或圖計算引擎)會用深度優先搜索(DFS)方式,通過窮舉全部可能的深度為K跳的路徑來試圖找到全部路徑和最終能抵達的終點。但是,DFS方式實現K鄰查詢有2個致命的缺點:

·效率低下:在體量稍大的圖中,不可能遍歷完全,例如Twitter數據集中常見的有超過百萬鄰居的頂點,如果以深度遍歷,復雜度是天文數字級的(百萬的11次方以上)?;

·結果大概率錯誤:即便是可以通過DFS完成遍歷,也沒有對結果進行分層,即無法判斷某個鄰居到底是位于第1跳還是第N跳。

我們先從驗證1度(1跳)鄰居開始,以Twitter數據集的頂點27960125為例。在源數據集中,如圖1所示,返回了8行(對應圖數據庫中的8條邊)?,但是它的1度鄰居到底是幾個呢?

圖1:Twitter源數據中頂點關聯的邊


正確答案是7個,注意圖1中頂點27960125的一個鄰居27498091出現了2次,它們之間存在兩條相互的關系(對應源數據集中的2行)?。但是作為去重后的1度鄰居集合,只有7個。

在圖2中,我們以無向圖(即雙向邊遍歷)的方式對頂點27960125進行1度鄰居查詢,得到全部鄰居頂點為7個。

圖2:在命令行工具中驗證頂點的鄰居結果集:嬴圖-CLI)


為了更精準地驗證結果正確性,對K鄰查詢還可以按照邊的方向來進行過濾,例如只查詢頂點2796015的出邊、入邊或雙向邊(默認是查詢雙向邊關聯的全部鄰居)?。圖3展示了如何通過圖查詢語言來完成相應的工作。注意,該頂點有6條出邊對應的1跳鄰居、2條入邊對應的1跳鄰居,其中有1個鄰居27498091是重疊的。

圖3::從嬴圖-CLI命令行工具操作K鄰——3種遍歷模式


如果參考美國圖數據庫廠家Tigergraph在Github網站上公開的性能測試結果數據文件,其K鄰查詢的結果存在明顯的錯誤,例如圖7-14中頂點27960125的1-Hop結果僅返回6個鄰居。

圖4:Tigergraph的性能評測結果中的數據(Github.com)

Tigergraph的查詢結果錯誤有3個可能,并且具有典型性。

·構圖錯誤:只存儲了單向邊,沒有存儲反向邊,無法進行反向邊遍歷;

·查詢方式錯誤:只進行了單向查詢,沒有進行雙向遍歷查詢;

·圖查詢代碼實現錯誤:即沒有對結果進行有效的去重,這個在多跳K-Hop查詢中再繼續分析。

其中,構圖錯誤代表數據建模錯誤,這意味著業務邏輯不能在數據建模層面被準確反映。例如在反欺詐、反洗錢場景中,賬戶A收到了一筆來自賬戶B的轉賬,但是卻因為沒有存儲一條從A至B的反向邊而無法追蹤該筆交易,這顯然是不能容忍的。

查詢方式和查詢代碼邏輯錯誤同樣也會對結果造成嚴重影響——每一跳查詢雙向邊,在多跳情況下查詢復雜度指數級高于單向邊查詢,這也意味著Tigergraph如果正確地實現圖數據建模、存儲與查詢,其性能會指數級降低,并且存儲空間的占用也會成倍增加(存儲正向和反向邊的數據結構要比僅存儲單向邊復雜2倍以上)?,數據加載時間也會成倍增加。

如果我們繼續追溯頂點27960125的2-Hop結果集,就會發現結果的錯誤更加隱蔽,例如Tigergraph的2-Hop實際上僅僅返回了沿出邊遍歷的第2度鄰居結果(圖5)?,并且沒有對結果去重。其第2度鄰居數1128中含有重復的頂點,按照只進行出邊查詢得到的去重結果應該是1127——但是2-Hop的正確結果應該是533108(圖6)?,這兩者間有473倍的差異,即47300%的誤差!在2-Hop的結果中,就可以看到Tigergraph的查詢結果同時存在以上所述的3種錯誤——構圖錯誤、查詢方式錯誤、結果未去重錯誤。

圖5 :Tigergraph僅進行單向遍歷的錯誤的2-Hop結果(Github)

圖6:K-Hop查詢的4種遍歷查詢方式(嬴圖-CLI)


遺憾的是,類似的查詢結果錯誤問題在今天的圖數據庫市場并不是個例,我們在Neo4j、ArangoDB等系統中也發現因底層算法實現或接口調用等問題而出現的錯誤。

更為遺憾的是,有多個廠家的“自研圖數據庫”實際上是對Neo4j社區版或ArangoDB的封裝,姑且不論這么操作是否涉嫌違規商用,暴力封裝幾乎注定了它們的查詢結果也是錯誤的。例如Neo4j默認并不對K鄰查詢結果集進行去重,而一旦開啟去重,它的運行效率會指數級下降;而ArangoDB有一種最短路徑查詢模式,只返回一條路徑,這種模式本身就是對最短路徑的錯誤理解與實現。

圖數據庫配套的可視化工具可以幫助我們更直觀、便捷地查詢結果的正確性。

上面介紹了圖上的基礎查詢K鄰查詢的正確性驗證方法,以及可能出現的錯誤情形。還有很多其他圖操作同樣也涉及結果錯誤的問題,但是都能通過一些基礎的方法來驗證。下面再舉2個有代表性的例子:最短路徑和圖算法。

最短路徑可以看作K鄰查詢的一個自然延展,區別在于它需要返回的結果有2個特征:

·高維結果:最短路徑需要返回多條由頂點、邊按遍歷順序組合而成的路徑;

·全部路徑:任意兩個頂點間可能存在多條最短路徑,如果是轉賬網絡、反洗錢網絡、歸因分析等查詢,只計算一條路徑顯然是無法反映全貌的。

以Twitter數據集中的頂點12、13之間的最短路徑為例,它們之間存在兩條最短路徑(圖7)?,其中一條由12指向13,另一條由13指向12(圖8)?,這個在源數據中也可以通過grep操作得到快速驗證。在更復雜(更深度)的查詢中,可以用類似的邏輯,通過層層的抽絲剝繭來驗證結果的正確性。

圖7:最短路徑結果示意(嬴圖 - CLI)
圖8:最短路徑查詢操作結果驗證——3種遍歷模式(嬴圖 - CLI)


下面以杰卡德相似度算法為例來說明如何驗證圖算法的正確性。以圖9為例,計算A、B兩個頂點間的相似度,計算公式如下:

圖9:小圖集


在圖9中,A、B節點的共同鄰居數為2,全部鄰居數為5,我們可以手工推算出這兩個節點的杰卡德相似度為2/5=0.4。直接調用杰卡德相似度算法的結果也應該是0.4(40%)?。如果用圖查詢語言來白盒化實現,代碼邏輯如圖10所示。

圖10:杰卡德相似度的圖查詢語言實現(嬴圖-GQL查詢語言)

在Twitter數據集中,任意兩個頂點間的杰卡德相似度計算的復雜度和被查詢頂點的1度鄰居的個數直接相關,以頂點12、13為例,它們都是典型的有百萬鄰居的“超級節點”?,在這種情況下,手工驗證結果的準確性并不現實。但是可以通過多組查詢來校驗結果是否正確,邏輯分為如下5步:

1)運行杰卡德相似度算法,如圖11所示:

圖11:直接運行杰卡德相似度算法

2)?(驗證方法一)通過多句查詢計算杰卡德相似度,如圖12所示:

圖12:杰卡德相似度算法——驗證方法一

3)?(驗證方法二)查詢頂點12的1跳鄰居個數(圖13)?。

4)?(驗證方法二)查詢頂點13的1跳鄰居個數(圖13)?。

圖13 :杰卡德相似度算法——驗證方法二第1部分

5)?(驗證方法二)查詢頂點12到13之間的全部深度為2的路徑(圖14)?,這一結果就是兩個頂點之間的全部共有鄰居。

圖14 杰卡德相似度算法——驗證方法二第2部分

?6)?(驗證方法二)用以上第5步的結果除以(第3步結果+第4步結果–第5步結果)=0.15362638。如果以上兩種驗證方法結果均一致,則圖算法計算結果正確。

最后要說的是,本文等于非常詳細地介紹了如何在圖數據庫上進行查詢正確性驗證的方法,希望可以為聰明的朋友們以開闊思路,以達到舉一反三、去偽存真的效果!!! 好了,洋洋灑灑有一大篇,就此打住。88!

· END ·


(文/Ricky - HPC高性能計算與存儲專家、大數據專家、數據庫專家及學者)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/72005.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/72005.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/72005.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Rust ~ Vec<u8>和[u8]

Vec<u8> 和 &[u8] 是兩種不同的數據類型&#xff0c;它們都與字節序列相關&#xff0c;但在所有權、內存管理、使用場景等方面存在明顯區別 類型本質 Vec<u8>&#xff1a;Rust 中的動態數組類型&#xff0c;即向量&#xff08;vector&#xff09;。它是一個擁…

MYSQL學習筆記(十):約束介紹(如:非空、唯一、主鍵、外鍵、級聯、默認、檢查約束)

前言&#xff1a; 學習和使用數據庫可以說是程序員必須具備能力&#xff0c;這里將更新關于MYSQL的使用講解&#xff0c;大概應該會更新30篇&#xff0c;涵蓋入門、進階、高級(一些原理分析);這一篇講解“約束”&#xff0c;如&#xff1a;非空、唯一、主鍵、外鍵、級聯、默認…

樹莓百度百科更新!宜賓園區業務再添新篇

樹莓集團宜賓園區業務不斷拓展&#xff0c;主要體現在以下幾個方面&#xff1a; 產業布局 -聚焦數字經濟核心領域&#xff1a;涵蓋軟件開發、人工智能、大數據等&#xff0c;吸引眾多上下游企業入駐&#xff0c;形成從芯片研發、軟件開發到系統集成的完整產業鏈條。 -推進“雙…

Halcon 學習之路 set_grayval 算子

gen_imag_const 創建灰度圖像 gen_image_const(Image&#xff0c;Type&#xff0c;Width&#xff0c;Height) 算子gen_image_const創建指定大小的圖像&#xff0c;圖像的寬度和高度由Width和Height決定 Type 像素類型 byte :每像素1字節&#xff0c;無符號&#xff08;0-255&…

03_pyqt5 + vlc 實現視頻播放器

1.功能需求如圖 按鈕: 播放/暫停, 前進/后退, 視頻上一個/下一個, 打開視頻進度條: 視頻進度條顯示, 進度條拖拽, 音量控制按鍵控制: 1,2,3,4縮放畫面大小, 2.方案選擇 開發語言: python UI界面: pyqt5 qt_designed 設計ui布局 視頻編碼: python-vlc 方案說明: 視頻解碼可…

使用vscode導出Markdown的PDF無法顯示數學公式的問題

我的硬件環境是M2的MacBook air&#xff0c;在vscode中使用了Markdown PDF來導出md文件對應的PDF。但不管導出html還是PDF文件&#xff0c;數學公式都是顯示的源代碼。 我看了許多教程&#xff0c;給的是這個方法&#xff1a;在md文件對應的html文件中加上以下代碼&#xff1a…

Java 網絡編程(二)—— TCP流套接字編程

TCP 和 UDP 的區別 在傳輸層&#xff0c;TCP 協議是有連接的&#xff0c;可靠傳輸&#xff0c;面向字節流&#xff0c;全雙工 而UDP 協議是無連接的&#xff0c;不可靠傳輸&#xff0c;面向數據報&#xff0c;全雙工 有連接和無連接的區別是在進行網絡通信的時候&#xff0c;…

MySQL 事務筆記

MySQL 事務筆記 目錄 事務簡介事務操作事務四大特性并發事務問題事務隔離級別總結 事務簡介 事務&#xff08;Transaction&#xff09;是數據庫操作的邏輯單元&#xff0c;由一組不可分割的SQL操作組成。主要用于保證&#xff1a; 多個操作的原子性&#xff08;要么全部成功…

GPT1 與 GPT2 的異同

1.什么是GPT1&#xff1a; GPT1介紹了一種通過生成式預訓練&#xff08;Generative Pre-Training&#xff09;來提升語言理解能力的方法。這種方法首先在一個大型的未標注文本語料庫上進行語言模型的預訓練&#xff0c;然后針對具體的任務進行判別式微調&#xff08;discrimin…

Android Audio其他——數字音頻接口(附)

數字音頻接口 DAI,即 Digital Audio Interfaces,顧名思義,DAI 表示在板級或板間傳輸數字音頻信號的方式。相比于模擬接口,數字音頻接口抗干擾能力更強,硬件設計簡單,DAI 在音頻電路設計中得到越來越廣泛的應用。 一、音頻鏈路 1、模擬音頻信號 可以看到在傳統的…

kafka-leader -1問題解決

一. 問題&#xff1a; 在 Kafka 中&#xff0c;leader -1 通常表示分區的領導者副本尚未被選舉出來&#xff0c;或者在獲取領導者信息時出現了問題。以下是可能導致出現 kafka leader -1 的一些常見原因及相關分析&#xff1a; 1. 副本同步問題&#xff1a; 在 Kafka 集群中&…

DeepSeek基礎之機器學習

文章目錄 一、核心概念總結&#xff08;一&#xff09;機器學習基本定義&#xff08;二&#xff09;基本術語&#xff08;三&#xff09;假設空間&#xff08;四&#xff09;歸納偏好&#xff08;五&#xff09;“沒有免費的午餐”定理&#xff08;NFL 定理&#xff09; 二、重…

【jira】用到幾張表

jira用到的幾張表 測試計劃&#xff0c;測試周期&#xff0c;測試用例&#xff0c;問題記錄 1. 測試計劃 # 記錄表&#xff0c;查計劃詳情 SELECT ID,issuenum,SUMMARY FROM jiraissue where issuenum 22871# 測試計劃下&#xff0c;測試周期&#xff0c;查測試周期id&…

Mysql 死鎖場景及解決方案

一、常見死鎖場景 1. 不同順序的鎖獲取 場景&#xff1a;事務A按順序更新 行1 → 行2&#xff0c;事務B按 行2 → 行1 順序更新。 原因&#xff1a;雙方各持有一把鎖&#xff0c;同時請求對方持有的鎖&#xff0c;形成循環等待。 2. 索引缺失導致鎖升級 場景&#xff1a;更…

Spring Boot從入門到精通:一站式掌握企業級開發

前言 Spring Boot作為Java領域最流行的微服務框架&#xff0c;憑借其約定優于配置的理念和快速啟動的特性&#xff0c;極大簡化了Spring應用的初始搭建和開發過程。本文將帶你從零開始系統學習Spring Boot&#xff0c;最終實現精通級應用開發&#xff0c;涵蓋核心原理、實戰技…

【Go】十六、protobuf構建基礎服務信息、grpc服務啟動的基礎信息

商品服務 服務結構 創建 goods 服務&#xff0c;將之前 user 服務的基本結構遷移到 goods 服務上&#xff0c;完整目錄是&#xff1a; mxshop_srvs user_srv … tmp … goods_srv config config.go 配置的讀取表 global global.go 數據庫、日志初始化、全局變量定義 handler …

Redis 持久化方式:RDB(Redis Database)和 AOF(Append Only File)

本部分內容是關于博主在學習 Redis 時關于持久化部分的記錄&#xff0c;介紹了 RDB 和 AOF 兩種持久化方式&#xff0c;詳細介紹了持久化的原理、配置、使用方式、優缺點和使用場景。并對兩種持久化方式做了對比。文章最后介紹了 Redis 持久化的意義并與其他常見的緩存技術做了…

Linux中lshw相關的命令

? lshw&#xff08;List Hardware&#xff09;是一個在 Linux 系統中用于顯示硬件詳細信息的強大工具。以下是一些常見的 lshw 相關命令及其用法&#xff1a; 1. 安裝 lshw 在使用 lshw 之前&#xff0c;你可能需要先安裝它。不同的 Linux 發行版安裝方式有所不同&#xff1…

爬蟲第九篇-結束爬蟲循環

最近在學習Python爬蟲的過程中&#xff0c;遇到了一個很有趣的問題&#xff1a;如何優雅地結束爬蟲循環&#xff1f;今天&#xff0c;我想和大家分享一下我的發現和心得。 一、爬蟲循環結束的常見問題 在寫爬蟲時&#xff0c;我們經常會遇到這樣的情況&#xff1a;當爬取到的…

Vue3狀態管理新選擇:Pinia使用完全指南

一、為什么需要狀態管理&#xff1f; 在Vue應用開發中&#xff0c;當我們的組件樹變得復雜時&#xff0c;組件間的數據傳遞會成為棘手的問題。傳統方案&#xff08;如props/$emit&#xff09;在多層嵌套組件中會變得笨拙&#xff0c;這時狀態管理工具應運而生。Vue3帶來了全新…