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支持的三值運算邏輯,這套邏輯支撐起了文章開始時所述的查詢,也遵循了語義網等模型的開放世界假設。

 

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章