天天看點

JanusGraph的schema及資料模組化

每個JanusGraph都有一個schema,該schema由edge labels, property keys和vertex labels組成。JanusGraph的schema可以顯式或隐式建立,推薦使用者采用顯式定義的方式。JanusGraph的schema是可以在使用過程中修改的,而且不會導緻服務當機,也不會拖慢查詢速度。

注意:通關系型資料庫不同,圖資料的schema是定義一張圖,而非定義一個vertex的。在Mysql中,我們通常将建立一張表定義為建立一個schema,而在JanusGraph中,一個Graph用于一個schema。

組成結構如下:

JanusGraph Schema

            | 

            |-----------Vertex Lables

            |

            |-----------Property Keys

            |-----------Edge Labels

Schema Type如edge label, vertex label及property key在元素首次建立時被賦予元素,且不能修改。

Definging Edge Labels

每個連接配接了兩個vertex的edge都有一個label,用于表示關系的語義。例如一個edge label:friend表明了兩個vertex有朋友關系。

要定義edge lable,調用makeEdgeLabel(String)方法,該方法傳回一個builder,可以通過該builder設定edge的多樣性(multiplicity),多樣性屬性定義了具有該label的edge的多樣性限制,也即在一個vertex間的最大edge的個數。JanusGraph支援如下多樣性。

Edge Label Multiplicity(邊的标簽多樣性)

  • MULTI

在一對vertex間可以有任意多個同樣label的edge。

  • SIMPLE

在一對vertex間最多隻能有一個同樣label的edge。

  • MANY2ONE

圖中任意一個Vertex最多有一個出度(outgoing)edge,和不限個數的入度(incoming)edge,注意:這些對edge的限制對同一個label生效。例如:

                          Label: mother

    (大兒子)---------------------------------->|

    (二兒子)---------------------------------->|------------------------>(母親)

    (小兒子)---------------------------------->|

  • ONE2MANY

圖中任意一個Vertex最多有一個入度(incoming)edge,和不限個數的出度(outgoing)edge,注意:這些對edge的限制對同一個label生效。例如:

                            Label:winnerof

                                                          |-------------------------->(game1)

    (person)--------------------------->|-------------------------->(game2)

                                                          |-------------------------->(game3)

  • ONE2ONE

某verex中具有同樣Label的edge,隻能有最多一個incoming edge和最多一個outgoing edge。

預設的多樣性設定為MULTI,設定方法如下所示:

mgmt = graph.openManagement()
follow = mgmt.makeEdgeLabel('follow').multiplicity(MULTI).make()
mother = mgmt.makeEdgeLabel('mother').multiplicity(MANY2ONE).make()
mgmt.commit()      

Defining Property Keys

vertex和edge上的property是鍵值對,如name="Danie",中name就是鍵,value則是Danie,Property Key是Graph Schema中的一部分,并且也用限制value的值類型。

Property Key Data Type

使用dataType定義某個property key的資料類型,JanusGraph強制具有相同Key的value都有相同的資料類型來保證加入到圖中的資料是有效的。

可以将某個property key的資料類型定義為Object.class來使該value存儲任何值(可序列化的),但是還是推薦使用具有具體類型的值類型。設定的類的名稱必須是一個确切的類而且不能是接口或抽閑類。JanusGraph提供了class 相等性,所有設定為子類型也是不可以的。

JanusGraph提供如下的資料類型:

JanusGraph的schema及資料模組化

Property Key Cardinality(屬性key基數)

使用cardinality(Cardinality)來定義Vertex上某個指定key的value的基數。

  • SINGLE

每個KEY隻允許一個VALUE

  • LIST

以LIST形式儲存VALUE,也即可以有重複值。

  • SET

以SET形式儲存VALUE,不能有重複值。

預設的cardinality是SINGLE,是以試圖向預設property中寫入多個值是不可以的。

mgmt = graph.openManagement()
//建立了一個名字為birthDate的屬性,并設定值類型為LONG,且隻能儲存一個值
birthDate = mgmt.makePropertyKey('birthDate').dataType(Long.class).cardinality(Cardinality.SINGLE).make()
//建立了一個名字為name的屬性,并設定值類型為String,且可以儲存不能重複的多個值
name = mgmt.makePropertyKey('name').dataType(String.class).cardinality(Cardinality.SET).make()
//建立了一個名字為sensorReading的屬性,并設定值類型為Double,且可以儲存可以重複的多個值
sensorReading = mgmt.makePropertyKey('sensorReading').dataType(Double.class).cardinality(Cardinality.LIST).make()
mgmt.commit()      

Relation Types

Edge Labels和property keys結合起來被稱為relation types,relation type的在圖中必須唯一,也意味着property key和edge label不能有相同的名字。在JanusGraph中有查詢relation type的API。

mgmt = graph.openManagement()
if(mgmt.containsRelationType('name'))
name = mgmt.getPropertyKey('name')
mgmt.getRelationTypes(EdgeLabel.class)
mgmt.commit()      

Defining Vertex Labels

類似于edge,vertex也有label,但與edge不同的是,edge label是可選的,可用于區分不同類型的vertex,如user vertex和product vertex。

雖然vertex label無論在概念還是資料模型層面都是可選的,但JanusGraph為所有的vertex都指定了一個label,addVertex()方法建立的vertex都使用了janusGraph的預設vertex label。vertex label在graph中必須是唯一的。

下面是建立代碼:

mgmt = graph.openManagement()
person = mgmt.makeVertexLabel('person').make()
mgmt.commit()
// Create a labeled vertex
person = graph.addVertex(label,'person')
// Create an unlabeled vertex
v = graph.addVertex()
graph.tx().commit()      

Automatic Schema Maker(自動建立schmea)

如果edge label, property key和vertex label沒有被顯式建立,則會在第一次使用時通過預設DefaultSchemaMaker建立。

預設的,隐式建立的edge label的multiplicity被設定為MULTI;隐式建立的property key設定為SINGLE,value資料類型為Object.class。使用者可以通過實作和注冊自己的DefaultSchemaMaker來自定義。

強烈建議使用者顯式建立,并配置系統為不支援隐式建立。

schema.default=none      

Changing Schema Elements

edge label,property key和vertex label的定義一旦送出到graph就不能修改了,但是schema元素的名字是可以修改的。通過JanusGraphManagement.changeName(JanusGraphSchemaElement, String)。

mgmt = graph.openManagement()
place = mgmt.getPropertyKey('place')
mgmt.changeName(place,'location')
mgmt.commit()      

需要注意的是,更新schema element的名稱可能不會立即可見,需要等待JanusGraph同步資料或後端資料同步完成。在更名可能導緻沖突的情況下,可能要重新開機執行個體。如果需要更名,可以先将原來元素改名為新的不存在的元素名稱,然後建立新的schema 元素,但不會影響已經建立的資料,需要通過批處理修改資料。

繼續閱讀