天天看點

Knowledge Graph |(1)圖資料庫Neo4j簡介與入門

基本概念

圖資料庫(Grahp Database)是基于圖論實作的一種新型NoSQL資料庫,它的存儲結構和資料的查詢方式都是以圖論為基礎的,圖論中圖的基本元素為節點和邊,在圖資料庫中對應的就是節點和關系。

在圖資料中,資料與資料之間的關系通過節點和關系構成一個圖結構并在此結構上實作資料庫的所有特性,具有傳統資料庫的所有功能。

與傳統的關系資料庫相同,圖資料庫的核心也是建構在一個引擎之上的,就是圖計算引擎,圖計算引擎是能夠組織存儲大型圖資料集并且實作了全局圖計算算法的一種資料庫核心建構。

目前較為流行的圖計算引擎有兩種:單機圖計算引擎和分布式圖計算引擎

單機圖計算引擎的典型代表是Cassovary,Cassovary是一個用scala編寫的基于java虛拟機的圖計算引擎,在twitter上Cassovary用來為其提供基于圖的功能。

分布式圖計算引擎的典型代表是pegasus和giraph,pegasus是一個運作在hadoop雲計算平台之上的分布式圖計算引擎,最初他是為了google的網頁資料處理而設計出來的。

圖資料庫與關系資料庫的對比

關系資料庫的弊端

關系資料庫自上世紀80年代以來一直是資料庫領域發展的動力,并持續到今天。他們兩高度結構化的資料存在在一張二維表中,并且資料組織的特性嚴格,在關系型資料庫中,通過外鍵限制來實作兩表或多個表之間某些記錄的互相引用關系,外鍵限制是關系資料庫中實作兩表之間互相引用必不可少的政策。但這種關系比對的操作,會消耗大量系統的資源,如果使用多對多的關系,則必須通過增加中間表來建立一對一的聯系,這相同的增加了操作成本。

圖資料模型的優勢

在圖資料庫中,關系是最重要的元素,通過關系我們能夠将節點互相關聯起來,用來構造一個負責的模型。圖資料庫模型中的每個節點都直接包含一個關系清單,關系清單中存放此節點與其他節點的關系記錄,這些關系記錄按類型和方向組織起來,并且還可以在上儲存附加屬性,将關系預先儲存到關系清單中的這種能力是Neo4j能夠提供比關系資料庫高幾個量級的性能,特别是對于複雜連接配接的查詢,neo4j能夠實作毫秒級的響應。

neo4j的體系結構

neo4j最初的設計動機是為了更好的描述實體之間的聯系,現實生活中,每個實體都與周圍的其他實體有着千絲萬縷的關系,這些關系中存在着大量的潛在資訊,但是傳統的關系型資料庫更加注重刻畫實體内部的屬性,實體與實體之間的關系往往需要通過外鍵來實作,是以,在查詢一個實體的關系時需要join操作,特别是深層次的關系查詢需要大量的join操作,而join操作通常又非常的耗時,特别是深層次的關系查詢時需要大量的join操作,而join操作通常又非常的耗時,是以為了應對海量資料查詢深層關系時的性能問題、以及運算負責性,neo4j應運而生。

Knowledge Graph |(1)圖資料庫Neo4j簡介與入門

免索引鄰接

neo4j有一個重要的特點,就是用來保證關系查詢的速度,即免索引鄰接屬性,資料庫中的每個節點都會維護與它相鄰節點的引用。是以每個節點都相當于與它相鄰節點的微索引,這比使用全局索引的代價小很多,這就意味着查詢時間和圖的整體規模無關,隻與它附近節點的數量成正比。在關系資料庫中使用全局索引引接各個節點,這些索引對每個周遊都會增加一個中間層,是以會導緻非常大的計算成本,而免索引鄰接為圖資料庫提供了快速、高效的圖周遊能力。

neo4j底層存儲結構

 免索引鄰接是圖資料實作高效周遊的關鍵,那麼免索引鄰接的實作機制就是neo4j底層存儲結構設計的關鍵。能夠支援高效的、本地化的圖存儲以及支援任意圖算法的快速周遊,是使用圖資料庫的重要原因。

從宏觀角度講,neo4j隻存在兩種資料類型:

(1)節點:節點類似于ER圖中的實體,每一個實體可以有零個或多個屬性,這些屬性以key-value對的形式存在,屬性沒有特殊類别的要求,同時每個節點還具有相應的标簽,用來區分不同類型的節點。

(2)關系:關系也類似ER圖中的關系,一個關系有起始節點和終止節點,另外,關系也能夠有自己的屬性和标簽。

在深入學習圖形資料庫之前,首先了解屬性圖的基本概念。一個屬性圖是由頂點(Vertex),邊(Edge),标簽(Lable),關系類型和屬性(Property)組成的有向圖。頂點也稱作節點(Node),邊也稱作關系(Relationship);在圖形中,節點和關系是最重要的實體,所有的節點是獨立存在的,為節點設定标簽,那麼擁有相同标簽的節點屬于一個分組,一個集合;關系通過關系類型來分組,類型相同的關系屬于同一個集合。關系是有向的,關系的兩端是起始節點和結束節點,通過有向的箭頭來辨別方向,節點之間的雙向關系通過兩個方向相反的關系來辨別。節點可有零個,一個或多個标簽,但是關系必須設定關系類型,并且隻能設定一個關系類型。Neo4j圖形資料庫的查詢語言是Cypher,用于操作屬性圖,是圖形語言中事實上的标準。

一、圖形資料庫的基本概念

Neo4j建立的圖(Graph)基于屬性圖模型,在該模型中,每個實體都有ID(Identity)唯一辨別,每個節點由标簽(Lable)分組,每個關系都有一個唯一的類型,屬性圖模型的基本概念有:

實體(Entity)是指節點(Node)和關系(Relationship);路徑(Path)是指由起始節點和終止節點之間的實體(節點和關系)構成的有序組合;

每個實體都有一個唯一的ID;

每個實體都有零個,一個或多個屬性,一個實體的屬性鍵是唯一的;

每個節點都有零個,一個或多個标簽,屬于一個或多個分組;

每個關系都隻有一個類型,用于連接配接兩個節點;

标記(Token)是非空的字元串,用于辨別标簽(Lable),關系類型(Relationship Type),或屬性鍵(Property Key);

标簽:用于标記節點的分組,多個節點可以有相同的标簽,一個節點可以有多個Lable,Lable用于對節點進行分組;

關系類型:用于标記關系的類型,多個關系可以有相同的關系類型;

屬性鍵:用于唯一辨別一個屬性;

屬性(Property)是一個鍵值對(Key/Value Pair),每個節點或關系可以有一個或多個屬性;屬性值可以是标量類型,或這标量類型的清單(數組);

二、圖形示例

在下面的圖形中,存在三個節點和兩個關系共5個實體;Person和Movie是Lable,ACTED_ID和DIRECTED是關系類型,name,title,roles等是節點和關系的屬性。

Knowledge Graph |(1)圖資料庫Neo4j簡介與入門
實體包括節點和關系,節點有标簽和屬性,關系是有向的,連結兩個節點,具有屬性和關系類型。

1,實體

在示例圖形中,包含三個節點,分别是:

Knowledge Graph |(1)圖資料庫Neo4j簡介與入門

包含兩個關系,分别是:

  • 兩個關系類型:ACTED_IN和DIRECTED,
  • 兩個關系:連接配接name屬性為Tom Hank節點和Movie節點的關系,連接配接name屬性為Forrest Gump的節點和Movie節點的關系。

其中一個關系如下圖:

Knowledge Graph |(1)圖資料庫Neo4j簡介與入門

2,标簽(Lable)

在圖形結構中,标簽用于對節點進行分組,相當于節點的類型,擁有相同标簽的節點屬于同一個分組。一個節點可以擁有零個,一個或多個标簽,是以,一個節點可以屬于多個分組。對分組進行查詢,能夠縮小查詢的節點範圍,提高查詢的性能。

在示例圖形中,有兩個标簽Person和Movie,兩個節點是Person,一個節點是Movie,标簽有點像節點的類型,但是,每個節點可以有多個标簽。

Knowledge Graph |(1)圖資料庫Neo4j簡介與入門

3,屬性(Property)

屬性是一個鍵值對(Key/Value),用于為節點或關系提供資訊。一般情況下,每個節點都由name屬性,用于命名節點。

在示例圖形中,Person節點有兩個屬性name和born,Movie節點有兩個屬性:title和released,

關系類型ACTED_IN有一個屬性:roles,該屬性值是一個數組,而關系類型為DIRECTED的關系沒有屬性

Knowledge Graph |(1)圖資料庫Neo4j簡介與入門

三、周遊(Traversal)

周遊一個圖形,是指沿着關系及其方向,通路圖形的節點。關系是有向的,連接配接兩個節點,從起始節點沿着關系,一步一步導航(navigate)到結束節點的過程叫做周遊,周遊經過的節點和關系的有序組合稱作路徑(Path)。

在示例圖形中,查找Tom Hanks參演的電影,周遊的過程是:從Tom Hanks節點開始,沿着ACTED_IN關系,尋找标簽為Movie的目标節點。

周遊的路徑如圖:

Knowledge Graph |(1)圖資料庫Neo4j簡介與入門

四、圖形資料庫的模式

Neo4j的模式(Schema)通常是指索引,限制和統計,通過建立模式,Neo4j能夠獲得查詢性能的提升和模組化的便利;Neo4j資料庫的模式可選的,也可以是無模式的。

1,索引

圖形資料庫也能建立索引,用于提高圖形資料庫的查詢性能。和關系型資料庫一樣,索引是圖形資料的一個備援副本,通過額外的存儲空間和犧牲資料寫操作的性能,來提高資料搜尋的性能,避免建立不必要的索引,這樣能夠減少資料更新的性能損失。

Neo4j在圖形節點的一個或多個屬性上建立索引,在索引建立完成之後,當圖形資料更新時,Neo4j負責索引的自動更新,索引的資料是實時同步的;在查詢被索引的屬性時,Neo4j自動應用索引,以獲得查詢性能的提升。

例如,使用Cypher建立索引:

CREATE INDEX ON :Person(firstname)

CREATE INDEX ON :Person(firstname, surname)

2,限制

在圖形資料庫中,能夠建立四種類型的限制:

節點屬性值唯一限制(Unique node property):如果節點具有指定的标簽和指定的屬性,那麼這些節點的屬性值是唯一的

節點屬性存在限制(Node property existence):建立的節點必須存在标簽和指定的屬性

關系屬性存在限制(Relationship property existence):建立的關系存在類型和指定的屬性

節點鍵限制(Node Key):在指定的标簽中的節點中,指定的屬性必須存在,并且屬性值的組合是唯一的

例如,使用Cypher建立限制:

CREATE CONSTRAINT ON (book:Book) ASSERT book.isbn IS UNIQUE;

CREATE CONSTRAINT ON (book:Book) ASSERT exists(book.isbn);

CREATE CONSTRAINT ON ()-[like:LIKED]-() ASSERT exists(like.day);

CREATE CONSTRAINT ON (n:Person) ASSERT (n.firstname, n.surname) IS NODE KEY;

3,統計資訊

當使用Cypher查詢圖形資料庫時,Cypher腳本被編譯成一個執行計劃,執行該執行計劃獲得查詢結果。為了生成一個性能優化的執行計劃,Neo4j需要收集統計資訊以對查詢進行優化。當統計資訊變化到一定的指派時,Neo4j需要重新生成執行計劃,以保證Cypher查詢是性能優化的,Neo4j存儲的統計資訊包括:

The number of nodes with a certain label.

Selectivity per index.

The number of relationships by type.

The number of relationships by type, ending or starting from a node with a specific label.

預設情況下,Neo4j自動更新統計資訊,但是,統計資訊的更新不是實時的,更新統計資訊可能是一個非常耗時的操作,是以,Neo4j在背景運作,并且隻有當變化的資料達到一定的門檻值時,才會更新統計資訊。

Neo4j keeps the statistics up to date in two different ways. For label counts for example, the number is updated whenever you set or remove a label from a node. For indexes, Neo4j needs to scan the full index to produce the selectivity number. Since this is potentially a very time-consuming operation, these numbers are collected in the background when enough data on the index has been changed.

Neo4j把執行計劃被緩存起來,在統計資訊變化之前,執行計劃不會被重新生成。通過配置選項,Neo4j能夠控制執行計劃的重新生成:

dbms.index_sampling.background_enabled:是否在背景統計索引資訊,由于Cypher查詢的執行計劃是根據統計資訊生成的,及時更新索引的統計資料對生成性能優化的執行計劃非常重要;

dbms.index_sampling.update_percentage:在更新索引的統計資訊之前,索引中有多大比例的資料被更新;

cypher.statistics_divergence_threshold:當統計資訊變化時,Neo4j不會立即更新Cypher查詢的執行計劃;隻有當統計資訊變化到一定的程度時,Neo4j才會重新生成執行計劃。