图数据库对 NULL 属性值支持情况

举报
你好_TT 发表于 2021/06/18 10:49:36 2021/06/18
【摘要】 NULL(空值)是数据库中对数据属性未知或缺失的一种标识,用于指示数据库中不存在的数据值。当图数据库中图数据的某个节点或边的属性值缺失或未定义时,该属性值即为NULL。

        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

        不支持NULLNOT 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支持的三值运算逻辑,这套逻辑支撑起了文章开始时所述的查询,也遵循了语义网等模型的开放世界假设。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。