模式設計和原則在知識圖譜中的應用
知識圖譜是一種非常強大的表示工具,它可以通過一張圖表達復雜的概念,這就是為什么常說“一圖勝千言”。但是,如果我們在沒有明確定義的模式下創建知識圖譜,就會存在一些問題。這就是為什么需要一種模式來限制鏈接的類型,充當文檔,提供和機器可讀的語義,并確保軟件按照預期的方式來組織信息。
對于知識圖譜而言,良好的模式設計比關系數據庫更為重要和核心。不幸的是,對于如何完成相對簡單的任務而言,目前缺乏詳細的指導。根據我的經驗,我想至少提供一些幫助。
為了更好地了解模式設計的模式和原則,我們可以使用TerminusCMS。雖然其中許多想法也適用于其他領域。
文檔(Documents)
在知識圖譜TerminusDB中,數據被視為由具有特定數據類型的字段組成的基本單元,這些字段可以是字符串、整數或日期等類型。這些基本單元會被組織成一個數據集合,稱為“文檔”。
舉個例子,我們可以看看“Person”文檔,以更好地理解這個概念。
這個人的信息包括姓名和出生日期,類似于關系型數據庫(RDBMS)或逗號分隔值(CSV)文件中的行記錄。為了讓數據更加豐富,可以添加一些額外的鏈接。
在知識圖譜中,我們可以將人與他們的朋友之間建立鏈接。這種數據結構非常適合用于社交網絡或聯系人管理應用程序。我們可以將每個人視為一個文檔,其中包含許多數據屬性,例如姓名和出生日期。此外,我們可以在文檔中添加指向其他文檔的鏈接,以建立人與他們的朋友之間的聯系。這種建模方式非常簡單和靈活,讓我們能夠方便地捆綁所有的數據屬性和鏈接在一起。
子文檔(Subdocuments)
有時,您需要在文檔中包含一個內部結構,這個結構不僅僅是一個數據原子,而是與該對象有緊密聯系,而不只是指向另一個對象的鏈接。這種類型的對象最常見的變體是注釋了一些附加結構的數據。例如,我們可能希望在某個時間范圍內得到數據點,該數據點具有特定的來源或可能有一個單位。
有時候一個數據原子的值本身并沒有意義,但是在特定對象的上下文中卻很有用,例如人的身高。為了表達這種內在聯系,我們可以使用子文檔,它可以將數據與額外的結構注釋關聯起來。使用"@subdocument" : []指定一個子文檔類,這個子文檔將完全屬于包含類,不允許其他人對其進行引用,并且當我們搜索包含文檔時,它將始終以完全擴展的 JSON 文檔返回。
您可能已經發現,“height”和“weight”都被表示為“UnitValue”,但是可能沒有使用正確的單位。為了確保單位的正確性,我們正在加入一些限制。
關系(Relationships)
并非所有關系都可以簡化為一個簡單的鏈接。xsd:decimal是表示數字的一種數據類型,然而,對于復雜的關系,通常可以使用子文檔來表示它們,就像我們使用單位裝飾基本類型以添加輔助信息一樣。如果您有一個復雜的關系,將其升級為一級對象通常是有意義的。例如,假設我們要表示股權關系,我們可以使用子文檔來描述持股人、股票數量、股份轉讓條款等詳細信息。
我們的Shareholding關系包含兩個不同的角色:持股公司和股東,他們可以是個人或公司。此外,我們還添加了關于這個關系的兩個附加信息:持股數量和持有時間。這種一流關系鏈接的方法可以擴展到處理超圖,即涉及兩個或更多對象的關系(例如接管)。
混合(Mixins):面向方面編程的多重繼承
在編程語言中,多重繼承是一種有效的工具,但在數據處理中,它更加實用?;旌鲜菙祿V锌芍貜褪褂玫囊环N方法,可以用來解決一些通用問題,例如空間、時間、來源和單位等。在我的建模經驗中,我發現這些通用問題在數據建模中屢次出現,它們是跨多個領域的共同問題。
時域范圍(Temporal Scope)
上面的例子Shareholding使用了時間組件,但該組件也可作為mixin(混入)在其他地方重用。mixin是一種可組合的代碼單元,可在不同類或對象中進行重復利用,以實現更高的代碼復用性和靈活性。因此,將時間組件提取為mixin可以在其他數據建模中方便地進行復用,提高建模效率和代碼質量。
在數據建模中,時間范圍的起始日期(from)是必須要有的,因為它描述了一些事情的開始時間。但是,結束日期(to)是可選的,這樣可以建模尚未結束的時間范圍。當然,并不總是需要這樣做,但通常這是一種非常有用的方法。
此外,我們可能還需要建模只發生一次的事件,即在某個特定時刻發生且不再重復發生的事件,例如一個人的生日或一場比賽的開始時間。
空間范圍(spatial scope)
在知識圖譜中,我們可以利用幾何形狀為對象添加空間范圍,這可以通過繼承來實現。我們可以將不同的幾何形狀組合在一起來表示空間范圍,例如矩形、圓形或多邊形。這種方法使我們能夠描述一個實體或概念在地理上的位置或空間范圍。
在這個上下文中,“Geometry”所指的是GeoJson中的一個類,具體指的是“Geometry類”。
溯源(Provenance)
為了更好地了解某些信息,通常需要記錄相關資源的來源。例如,當我們從網站等途徑獲取資源時,這種記錄就很常見。在這種情況下,我們可能需要創建一個繼承Event和Source類的對象來記錄這些信息。
集合體(Collections)
在知識圖譜中,有許多不同的方式可以對集合進行建模。TerminusDB 實現了三種不同的方法,旨在嘗試簡化建模過程,這三種方法是:Set、List和Array。了解這三種方法之間的差異非常重要:Set表示集合,List表示列表,而Array則表示數組。
集合(Set)
Set是三種集合模型中最簡單的一種,因為它沒有順序,實際上只是一條邊,可以包含多個元素。在圖中,具有三個元素的Set集合可以表示為以下形式:
數組(Array)
Array是一個更復雜的對象,它通過索引來對元素進行編碼,并且可以根據位置來訪問它們。與Sets和Lists不同,Array具有固定的大小,其元素是有序的。此外,Array還提供了一些額外的功能,使其與Sets和Lists區別開來。
數組中的每個值元素都有一個附加的(隱藏)間接對象,帶有索引(或多維數組的多個索引)。這使得我們不僅可以有順序,還可以有多個維度來表示“間隔”。當返回 JSON 中的值時,我們將返回一個多維數組,其中包含未填充區域的null字段。但實際上,這些未填充區域并沒有在數據庫中出現。
列表(List)
List 是直接從 RDF 數據中提取 rdf:List 并使用 rdf:first 和 rdf:rest 字段來表示。三個元素的列表結構如下所示:
鏈表式結構具有潛在的技術優勢。相較于數組,您可以在列表中的任何位置插入新元素,而不必在給定元素之后重新索引所有內容。但是,鏈表式結構需要遍歷圖中的長鏈來解碼列表,這可能會對性能產生影響。在列表非常長時,它可能會導致解碼時間顯著延長,因此需要權衡其優缺點來選擇適合特定場景的數據結構。
結論
通過使用知識圖譜,可以實現更加輕松地操作和發現數據。知識圖譜是一個基于圖形結構的數據模型,可以將各種實體和概念以及它們之間的關系表示為節點和邊,使得數據之間的關系和結構更加清晰和易于理解。在使用知識圖譜進行數據建模后,用戶可以方便地進行數據操作和發現,從而更加高效地利用數據。