点VID
在Nebula Graph中,一个点由点的ID唯一标识,即VID或Vertex ID。
VID的特点
VID数据类型只可以为定长字符串
FIXED_STRING(<N>)
或INT64
;一个图空间只能选用其中一种VID类型。VID在一个图空间中必须唯一,其作用类似于关系型数据库中的主键(索引+唯一约束)。但不同图空间中的VID是完全独立无关的。
点VID的生成方式必须由用户自行指定,系统不提供自增ID或者UUID。
VID相同的点,会被认为是同一个点。例如:
VID相当于一个实体的唯一标号,例如一个人的身份证号。Tag相当于实体所拥有的类型,例如”滴滴司机”和”老板”。不同的Tag又相应定义了两组不同的属性,例如”驾照号、驾龄、接单量、接单小号”和”工号、薪水、债务额度、商务电话”。
同时操作相同VID并且相同Tag的两条
INSERT
语句(均无IF NOT EXISTS
参数),晚写入的INSERT
会覆盖先写入的。同时操作包含相同VID但是两个不同
TAG A
和TAG B
的两条INSERT
语句,对TAG A
的操作不会影响TAG B
。
VID通常会被(LSM-tree方式)索引并缓存在内存中,因此直接访问VID的性能最高。
VID使用建议
Nebula Graph 1.x只支持VID类型为
INT64
,2.x支持INT64
和FIXED_STRING(<N>)
。在CREATE SPACE
中通过参数vid_type
可以指定VID类型。可以使用
id()
函数,指定或引用该点的VID;可以使用
LOOKUP
或者MATCH
语句,来通过属性索引查找对应的VID;性能上,直接通过VID找到点的语句性能最高,例如
DELETE xxx WHERE id(xxx) == "player100"
, 或者GO FROM "player100"
等语句。通过属性先查找VID,再进行图操作的性能会变差,例如LOOKUP | GO FROM $-.ids
等语句,相比前者多了一次内存或硬盘的随机读(LOOKUP
)以及一次序列化(|
)。
VID生成建议
VID的生成工作完全交给应用端,有一些通用的建议:
(最优)通过有唯一性的主键或者属性来直接作为VID;属性访问依赖于VID;
通过有唯一性的属性组合来生成VID,属性访问依赖于属性索引。
通过snowflake等算法生成VID,属性访问依赖于属性索引;
如果个别记录的主键特别长,但绝大多数记录的主键都很短的情况,不要将
FIXED_STRING(<N>)
的N
设置成超大,这会浪费大量内存和硬盘,也会降低性能。此时可通过BASE64,MD5,hash编码加拼接的方式来生成。如果用hash方式生成int64 VID:在有10亿个点的情况下,发生hash冲突的概率大约是1/10。边的数量与碰撞的概率无关。
定义和修改VID的数据类型
VID的数据类型必须在创建图空间时定义,且一旦定义无法修改。
“查询起始点”(start vid
)与全局扫描
绝大多数情况下,Nebula Graph 的查询语句(MATCH
, GO
, LOOKUP
)的执行计划,必须要通过一定方式找到查询起始点的 VID (start vid
)。
定位 start vid
只有两种方式:
例如
GO FROM "player100" OVER
是在语句中显式的指明start vid
是 “player100”;例如,
LOOKUP ON player WHERE player.name == "Tony Parker"
或者MATCH (v:player {name:"Tony Parker"})
,是通过属性player.name
的索引来定位到start vid
;
不能在没有 start vid
情况下进行全局扫描
例如 match (n) return n;
会返回错误,因为此时无法定位到 start vid
;这是一个全局扫描,因此被禁止。
最后更新: September 7, 2021