1. 程式人生 > 其它 >8種圖資料庫對 NULL 屬性值支援情況

8種圖資料庫對 NULL 屬性值支援情況

摘要:在語義網等圖模型中,遵循開放世界假設,對於資料中未包含的事實,都認為是未知的而非假的。

本文分享自華為雲社群《圖資料庫對 NULL 屬性值支援情況》,原文作者:你好_TT 。

NULL(空值)是資料庫中對資料屬性未知或缺失的一種標識,用於指示資料庫中不存在的資料值。當圖資料庫中圖資料的某個節點或邊的屬性值缺失或未定義時,該屬性值即為NULL。

那麼為什麼圖資料庫需要支援NULL值呢?

在語義網等圖模型中,遵循開放世界假設,對於資料中未包含的事實,都認為是未知的而非假的。例如對於一個包含若干學生的圖資料庫,有如下兩條查詢:

  • 查詢一:找出大學在清華大學的人
  • 查詢二:找出大學不在清華大學的人

如果圖資料庫中的小明同學沒有填寫學校,那麼小明是屬於查詢一的結果集,還是屬於查詢二的結果集。開放世界假設認為,未包含的資料是未知的而非虛假,在這個邏輯的支撐下,小明既不屬於查詢一的答案,也不屬於查詢二的答案。

圖資料庫,通過NULL值實現這一邏輯。

下面我們來看看各圖資料庫對NULL 屬性值的支援情況。

GDB

對於字串這種資料型別,支援長度為零的空字串,表示為:””,不使用雙引號的空白域表示不存在,為 nullptr。

NebulaGraph

預設情況下,插入點或邊時,屬性值可以為 NULL ,使用者也可以設定屬性值不允許為 NULL (NOT NULL),即插入點或邊時必須設定該屬性的值,除非建立屬性時已經設定預設值。

HugeGraph

可以指定一些字串代表空值,比如"NULL",如果該列對應的頂點/邊屬性又是一個可空屬性,那在構造頂點/邊時不會設定該屬性的值。

Amazon Neptune

允許輸入空白欄位,一個空白欄位被認為是一個NULL值。

Neo4j

在Cypher中,NULL用於表示缺失或者未定義的值。從概念上講,NULL意味著缺失的未知的值,它的處理方式與其他值的處理方式略有不同。

Gremlin

TinkerGraph可以配置為支援NULL作為屬性值,但並不是所有的圖資料庫產品都支援。所以在使用之前請務必檢查supportsNullPropertyValues()的功能或檢視說明文件。

TigerGraph

不支援NULL和NOT NULL 屬性。圖資料庫中不支援NULL這個值。如果在建立頂點或邊例項時未為屬性賦值,則以該資料型別的預設值為該屬性賦值,最新版本已經廢除這條。

華為雲圖引擎服務GES

支援NULL屬性值。當輸入空白欄位時,認為該屬性值為NULL。

下面舉例說明,假設匯入資料的schema為:

<label name="movie">
    <properties>
        <property name="ChineseName" cardinality="single" dataType="string"/>
        <property name="Year" cardinality="single" dataType="int"/> 
    </properties>
</label>
<label name="user">
    <properties>
        <property name="Gender" cardinality="single" dataType="enum" typeNameCount="2" typeName1="F" typeName2="M"/>
        <property name="School" cardinality="single" dataType="string"/>
        <property name="Age" cardinality="single" dataType="int"/>
    </properties>
</label>
<label name="rate">
    <properties> 
        <property name="Datetime" cardinality="single" dataType="date"/>
        <property name="Score" cardinality="single" dataType="double" />
    </properties>
</label>  

匯入的點資料為:

張三,user,M,清華大學
李四,user,,北京大學,20
小明,user,,,21
Titanic,movie,泰塔尼克號,1997

匯入的邊資料為:

張三,Titanic,rate,,4

呼叫GES原生API介面進行邊查詢:

GET http://{SERVER_URL}/ges/v1.0/{project_id}/graphs/{graph_name}/edges/detail? source=張三&target=Titanic

得到結果:

"edges": [
    {
        "index": "0",
        "source": "張三",
        "label": "rate",
        "properties": {
            "Score": [
                4.0
            ],
            "Datetime": [
                null
            ]
        },
        "target": "Titanic"
    }
]

可以看到,查詢到的邊的 Datetime 的屬性值是 null , 這是因為該屬性欄位輸入時是空白欄位。

另外,GES 支援 Gremlin 和 Cypher 兩種主流的圖查詢語言,下面我們通過 Cypher 驗證文章開始時提出的問題。

分別進行以下三個查詢:

match (n:user) where n.School='清華大學' return n
match (n:user) where n.School<>'清華大學' return n
match (n:user) where n.School is null return n

得到的查詢結果分別為:

"row": [
    {
        "School": "清華大學",
        "Gender": "M",
        "Age": null
    }
],
"meta": [
    {
        "id": "張三",
        "type": "node",
        "labels": [
            "user"
        ]
    }
]

"row": [
    {
        "School": "北京大學",
        "Gender": null,
        "Age": 20
    }
],
"meta": [
    {
        "id": "李四",
        "type": "node",
        "labels": [
            "user"
        ]
    }
]

"row": [
    {
        "School": null,
        "Gender": null,
        "Age": 21
    }
],
"meta": [
    {
        "id": "小明",
        "type": "node",
        "labels": [
            "user"
        ]
    }
]

當 n.School 為 null 時,n.School<>'清華大學' 和 n.School='清華大學' 的返回值都是非 true,所以小明未在前兩個查詢的結果集中。這背後是GES Cypher支援的三值運算邏輯,這套邏輯支撐起了文章開始時所述的查詢,也遵循了語義網等模型的開放世界假設。

點選關注,第一時間瞭解華為雲新鮮技術~