Nebula基础
这里只是对Nebula基础的介绍,其目的是为了让未接触过Nebula的同学最短时间了解其概念和使用。更详细更准确的内可以查看官方文档。 docs.nebula-graph
其他内容
基础概念
要理解 Nebula 的语句,首先需要掌握其基本的数据概念。以下是 Nebula 数据模型的基本要点,涵盖图、点、边、属性、标签和类型的详细介绍:
-
图(Graph):
图是由节点和边组成的数据结构,用于展示实体之间的关系。图可以划分为多个子图(Graph Space),每个子图都包含一组相关的节点和边。每个子图都可以有不同的模式、数据和配置。
-
点(Vertex):
点代表图中的实体,可以带有各种属性。在 Nebula 中,每个点都有一个唯一的标识符,称为
Vertex ID
。点用于表达现实世界中的实体。 -
标签(Tag):
标签是一组相同类型的点的集合,用于对点进行分类或分组。每个标签都有一个名称,点可以分配给一个或多个标签。标签在数据模型中提供更好的组织和查询能力。
-
边(Edge):
边表示图中的关联,将两个点连接起来。每个边都有一个起始节点和一个结束节点,以及一个唯一的标识符,称为
Edge ID
。边用于描述实体之间的联系。 -
边类型(Edge Type):
边类型用于区分不同类型的边。每条边都属于一个类型,类型可用于定义边的含义和语义。例如,可以使用不同类型来表示不同种类的关系。
-
属性(Property):
属性是与点和边相关的数据。每个点和边都可以拥有零个或多个属性,用于描述它们的特征、信息或状态。例如,人的点可以有姓名、年龄、性别等属性。
路径类型
在实际查询中,不同的路径查询方式会影响最终的查询结果。以下是几种路径类型,具体的路径解释可以查阅官方文档 docs.nebula-graph。
路径类型 | 说明 | 重复性 |
---|---|---|
walk | 由有限或无限的边序列构成 | 遍历时点和边可以重复 |
trail | trail 类型的路径由有限的边序列构成 | 遍历时只有点可以重复,边不可以重复 |
cycle | 是封闭的 trail 类型的路径 | 边不可以重复,起点和终点重复,并且没有其他点重复 |
circuit | 是封闭的 trail 类型的路径 | 边不可以重复,除起点和终点重复外,可能存在其他点重复 |
path | path 类型的路径由有限的边序列构成 | 遍历时点和边都不可以重复 |
边类型操作
创建边类型
语法
sql
CREATE EDGE [IF NOT EXISTS] <edge_type_name>
(
<prop_name> <data_type> [NULL | NOT NULL] [DEFAULT <default_value>] [COMMENT '<comment>']
[{, <prop_name> <data_type> [NULL | NOT NULL] [DEFAULT <default_value>] [COMMENT '<comment>']} ...]
)
[TTL_DURATION = <ttl_duration>]
[TTL_COL = <prop_name>]
[COMMENT = '<comment>'];
参数
参数 | 说明 |
---|---|
<prop_name> | 属性名称。每个 Edge type 中的属性名称必须唯一。属性的命名规则与 Edge type 相同。 |
<data_type> | 属性的数据类型,目前支持数值、布尔、字符串以及日期与时间。 |
NULL \ NOT NULL | 指定属性值是否支持为 NULL。默认值为 NULL。 |
DEFAULT | 指定属性的默认值。默认值可以是一个文字值或 NebulaGraph 支持的表达式。如果插入边时没有指定某个属性的值,则使用默认值。 |
COMMENT | 对单个属性或 Edge type 的描述。最大为 256 字节。默认无描述。 |
TTL_DURATION | 指定时间戳差值,单位:秒。时间戳差值必须为 64 位非负整数。属性值和时间戳差值之和如果小于当前时间戳,属性就会过期。默认值为 0,表示属性永不过期。 |
TTL_COL | 指定要设置存活时间的属性。属性的数据类型必须是 int 或者 timestamp。一个 Edge type 只能指定一个字段为 TTL_COL。 |
示例
sql
# 创建包含属性的 Edge type。
CREATE EDGE IF NOT EXISTS follow(degree int);
# 创建没有属性的 Edge type。
CREATE EDGE IF NOT EXISTS no_property();
# 创建包含默认值的 Edge type。
CREATE EDGE IF NOT EXISTS follow_with_default(degree int DEFAULT 20);
# 为字段属性设置超时时间。
CREATE EDGE IF NOT EXISTS e1(p1 string, p2 int, p3 timestamp) TTL_DURATION = 100, TTL_COL = "p2";
修改边类型属性
语法
sql
ALTER EDGE <edge_type_name>
<alter_definition> [, alter_definition] ...]
[ttl_definition [, ttl_definition] ... ]
[COMMENT = '<comment>'];
alter_definition:
| ADD (prop_name data_type)
| DROP (prop_name)
| CHANGE (prop_name data_type)
ttl_definition:
TTL_DURATION = ttl_duration, TTL_COL = prop_name
示例
目前并未找到修改属性名称的方式。
sql
CREATE EDGE IF NOT EXISTS e1(p1 string, p2 int);
# 新增字段
ALTER EDGE e1 ADD (p3 int, p4 string);
# 为字段设置超时时间
ALTER EDGE e1 TTL_DURATION = 2, TTL_COL = "p2";
ALTER EDGE e1 COMMENT = 'edge1';
# 移除字段属性
ALTER EDGE e1 DROP (p1);
查看边类型的属性
语法
sql
DESC[RIBE] EDGE <edge_type_name>
示例
sql
DESCRIBE EDGE FRIEND;
返回结果
Field | Type | Null | Default | Comment |
---|---|---|---|---|
year | int64 | YES | EMPTY | EMPTY |
删除边类型
语法
sql
DROP EDGE [IF EXISTS] <edge_type_name>
示例
sql
CREATE EDGE IF NOT EXISTS e1(p1 string, p2 int);
DROP EDGE e1;
为点添加边
语法
sql
INSERT EDGE [IF NOT EXISTS] <edge_type> ( <prop_name_list> )
VALUES
<src_vid> -> <dst_vid>[@<rank>] : ( <prop_value_list> )
[, <src_vid> -> <dst_vid>[@<rank>] : ( <prop_value_list> ), ...];
参数
参数 | 说明 |
---|---|
edge_type | 边关联的 Edge type,只能指定一个 Edge type。Edge type 必须提前创建。 |
prop_name_list | 需要设置的属性名称列表。 |
src_vid | 起始点 ID,表示边的起点 |
dst_vid | 目的点 ID,表示边的终点 |
rank | 可选项。边的 rank 值。数据类型为 int。默认值为 0 |
示例
sql
# 点 10 和 11 插入不包含属性的边。
CREATE EDGE IF NOT EXISTS e1();
INSERT EDGE e1 () VALUES "10"->"11":();
# 插入 rank 为 1 的边。
INSERT EDGE e1 () VALUES "10"->"11"@1:();
# 一次插入 2 条边。
INSERT EDGE e2 (name, age) VALUES "12"->"13":("n1", 1), "13"->"14":("n2", 2);
删除点的边信息
DELETE EDGE 语句可以删除边。一次可以删除一条或多条边。如果需要删除一个点的所有出边,请删除这个点。
语法
sql
# 语法 如果不指定 rank,则仅仅删除 rank 为 0 的边。
DELETE EDGE <edge_type> <src_vid> -> <dst_vid>[@<rank>] [, <src_vid> -> <dst_vid>[@<rank>] ...]
示例
sql
# 删除指定边语法
DELETE EDGE serve "player100" -> "team204"@0;
# 删除所有边语法
GO FROM "player100" OVER follow \
WHERE dst(edge) == "player101" \
YIELD src(edge) AS src, dst(edge) AS dst, rank(edge) AS rank \
| DELETE EDGE follow $-.src -> $-.dst @ $-.rank;
修改点的边信息
语法
sql
UPDATE EDGE ON <edge_type>
<src_vid> -> <dst_vid> [@<rank>]
SET <update_prop>
[WHEN <condition>]
[YIELD <output>]
参数
参数 | 说明 |
---|---|
edge_type | 边关联的 Edge type,只能指定一个 Edge type。Edge type 必须提前创建。 |
src_vid | 起始点 ID,表示边的起点 |
dst_vid | 目的点 ID,表示边的终点 |
WHEN | 更新条件 |
YIELD | 指定语句的输出格式 |
示例
sql
UPDATE EDGE ON serve "player100" -> "team204"@0 \
SET start_year = start_year + 1 \
WHEN end_year > 2010 \
YIELD start_year, end_year;
返回结果
start_year | end_year |
---|---|
1998 | 2016 |
新增或修改点直接的边
UPSERT EDGE 语句结合 UPDATE 和 INSERT,如果边存在,会更新边的属性;如果边不存在,会插入新的边。
语法
sql
UPSERT EDGE ON <edge_type>
<src_vid> -> <dst_vid> [@rank]
SET <update_prop>
[WHEN <condition>]
[YIELD <properties>]
参数
参数 | 说明 |
---|---|
edge_type | 边关联的 Edge type,只能指定一个 Edge type。Edge type 必须提前创建。 |
src_vid | 起始点 ID,表示边的起点 |
dst_vid | 目的点 ID,表示边的终点 |
rank | 可选项。边的 rank 值。数据类型为 int。默认值为 0 |
WHEN | 更新条件 |
YIELD | 指定语句的输出格式 |
示例
sql
UPSERT EDGE on serve "player149" -> "team219" \
SET end_year = end_year + 1 \
WHEN start_year == 2016 \
YIELD start_year, end_year;
TAG操作
标签是一组相同类型的点的集合,用于对点进行分类或分组。每个标签都有一个名称,点可以被分配一个或多个标签。标签在数据模型中提供了更好的组织和查询能力。
创建
语法
sql
CREATE TAG [IF NOT EXISTS] <tag_name>
(
<prop_name> <data_type> [NULL | NOT NULL] [DEFAULT <default_value>] [COMMENT '<comment>']
[{, <prop_name> <data_type> [NULL | NOT NULL] [DEFAULT <default_value>] [COMMENT '<comment>']} ...]
)
[TTL_DURATION = <ttl_duration>]
[TTL_COL = <prop_name>]
[COMMENT = '<comment>'];
参数
参数 | 说明 |
---|---|
<tag_name> | Tag的名称,每个图空间内的Tag必须是唯一的。Tag名称设置后无法修改。Tag名称以英文字母开头,支持1~4字节的UTF-8编码字符,包括英文字母(区分大小写)、数字、中文等,但是不包括除下划线外的特殊字符。使用特殊字符或保留关键字时,需要用反引号(`)包围且不能使用英文句号(.)。详情参见关键字和保留字。 |
<prop_name> | 属性名称。每个Tag中的属性名称必须唯一。属性的命名规则与Tag相同。 |
<data_type> | 属性的数据类型,目前支持数值、布尔、字符串以及日期与时间。 |
NULL \ NOT NULL | 指定属性值是否支持为NULL。默认值为NULL。 |
DEFAULT | 指定属性的默认值。默认值可以是一个文字值或NebulaGraph支持的表达式。如果插入点时没有指定某个属性的值,则使用默认值。 |
COMMENT | 对单个属性或Tag的描述。最大为256字节。默认无描述。 |
TTL_DURATION | 指定时间戳差值,单位:秒。时间戳差值必须为64位非负整数。属性值和时间戳差值之和如果小于当前时间戳,属性就会过期。默认值为0,表示属性永不过期。 |
TTL_COL | 指定要设置存活时间的属性。属性的数据类型必须是int或者timestamp。一个Tag只能指定一个字段为TTL_COL。更多TTL的信息请参见TTL。 |
示例
sql
# 创建一个有属性的标签
CREATE TAG IF NOT EXISTS player(name string, age int);
# 创建没有属性的标签
CREATE TAG IF NOT EXISTS no_property();
# 创建包含默认值的标签
CREATE TAG IF NOT EXISTS player_with_default(name string, age int DEFAULT 20);
# 对字段 create_time 设置 TTL 为 100 秒。
CREATE TAG IF NOT EXISTS woman(name string, age int, married bool, salary double, create_time timestamp) TTL_DURATION = 100, TTL_COL = "create_time";
修改
语法
sql
ALTER TAG <tag_name>
<alter_definition> [[, alter_definition] ...]
[ttl_definition [, ttl_definition] ... ]
[COMMENT = '<comment>'];
alter_definition:
| ADD (prop_name data_type [NULL | NOT NULL] [DEFAULT <default_value>] [COMMENT '<comment>'])
| DROP (prop_name)
| CHANGE (prop_name data_type [NULL | NOT NULL] [DEFAULT <default_value>] [COMMENT '<comment>'])
ttl_definition:
TTL_DURATION = ttl_duration, TTL_COL = prop_name
示例
sql
CREATE TAG IF NOT EXISTS t1 (p1 string, p2 int);
# 添加字段
ALTER TAG t1 ADD (p3 int, p4 string);
# 修改TTL
ALTER TAG t1 TTL_DURATION = 2, TTL_COL = "p2";
# 修改注释
ALTER TAG t1 COMMENT = 'test1';
# 添加字段属性,并设置默认值和NOT NULL
ALTER TAG t1 ADD (p5 double NOT NULL DEFAULT 0.4 COMMENT 'p5') COMMENT='test2';
详情
语法
sql
DESC[RIBE] TAG <tag_name>;
示例
sql
DESCRIBE TAG player;
输出结果
Field | Type | Null | Default | Comment |
---|---|---|---|---|
"name" | "string" | "YES" | ||
"age" | "int64" | "YES" |
删除TAG
语法
sql
DROP TAG [IF EXISTS] <tag_name>;
示例
sql
CREATE TAG IF NOT EXISTS test(p1 string, p2 int);
DROP TAG test;
点操作
空间和MySQL中的database概念类似。CREATE SPACE语句可以创建一个新的图空间,或者克隆现有图空间的Schema。
新增
语法
sql
INSERT VERTEX [IF NOT EXISTS] [tag_props, [tag_props] ...]
VALUES VID: ([prop_value_list])
tag_props: tag_name ([prop_name_list])
prop_name_list: [prop_name [, prop_name] ...]
prop_value_list: [prop_value [, prop_value] ...]
参数
参数 | 说明 |
---|---|
tag_name | 每个图空间内的Tag必须是唯一的。Tag名称设置后无法修改。Tag名称以英文字母开头,支持1~4字节的UTF-8编码字符,包括英文字母(区分大小写)、数字、中文等,但是不包括除下划线外的特殊字符。使用特殊字符或保留关键字时,需要用反引号(`)包围且不能使用英文句号(.),详情参见关键字和保留字。 |
property_name | 属性名称。每个Tag中的属性名称必须唯一。 |
vid | 点ID。 |
property_value | 根据prop_name_list填写属性值。 |
示例
sql
# 先创建标签和边类型
CREATE TAG IF NOT EXISTS aTag (at1 string, at2 int, at3 timestamp);
CREATE TAG IF NOT EXISTS bTag (bt1 string, bt2 int, bt3 timestamp);
CREATE EDGE IF NOT EXISTS aflow (af1 string, af2 int, af3 timestamp);
# 插入不包含属性的点。
INSERT VERTEX aTag() VALUES "1":();
# 插入包含标签aTag的点
INSERT VERTEX aTag (at1, at2) VALUES "2":("2", 2);
# 一次插入2个点。
INSERT VERTEX aTag (at1, at2) VALUES "3":("3", 3),"4":("4", 4);
# 一次插入两个Tag的属性到同一个点。
INSERT VERTEX aTag (at1, at2), bTag (bt1, bt2) VALUES "5": ("5", 5, "6", 6);
修改
语法
sql
UPDATE VERTEX ON <tag_name> <vid>
SET <update_prop>
[WHEN <condition>]
[YIELD <output>]
参数
参数 | 是否必须 | 说明 | 示例 |
---|---|---|---|
<tag_name> | 是 | 指定点的Tag。要修改的属性必须在这个Tag内。 | ON player |
是 | 指定要修改的点ID。 | "player100" | |
SET <update_prop> | 是 | 指定如何修改属性值。 | SET age = age + 1 |
WHEN | 否 | 指定过滤条件。如果结果为false,SET子句不会生效。 | WHEN name == "Tim" |
YIELD | 否 | 指定语句的输出格式。 | YIELD name AS Name |
示例
sql
UPDATE VERTEX ON aTag "5"
SET at2 = at2 + 2
WHEN at2 == 5
YIELD at1 AS at1, at2 AS at2;
新增或修改
UPSERT语句结合UPDATE和INSERT,如果边存在,会更新边的属性;如果边不存在,会插入新的边。
语法
sql
UPSERT VERTEX ON <tag> <vid>
SET <update_prop>
[WHEN <condition>]
[YIELD <output>]
参数
参数 | 是否必须 | 说明 | 示例 |
---|---|---|---|
<tag_name> | 是 | 指定点的Tag。要修改的属性必须在这个Tag内。 | ON player |
是 |
指定要修改的点ID。 | "player100" |
| SET <update_prop> | 是 | 指定如何修改属性值。 | SET age = age + 1 |
| WHEN | 否 | 指定过滤条件。如果结果为false,SET子句不会生效。 | WHEN name == "Tim" |
| YIELD | 否 | 指定语句的输出格式。 | YIELD name AS Name |
示例
sql
UPSERT VERTEX ON player "player101" \
SET age = age + 2 \
WHEN name == "Tony Parker" \
YIELD name AS Name, age AS Age;
删除
语法
sql
DELETE VERTEX <vid> [ , <vid> ... ] [WITH EDGE];
示例
sql
# 删除VID为`team1`的点,不删除该点关联的出边和入边。
DELETE VERTEX "team1";
# 删除VID为`team1`的点,并删除该点关联的出边和入边。
DELETE VERTEX "team1" WITH EDGE;
移除点的TAG
语法
sql
# Tag可以用*表示所有Tag
DELETE TAG <tag_name_list> FROM <VID>;
示例
sql
# 移除点指定标签
DELETE TAG test1 FROM "test";
# 移除点所有标签
DELETE TAG * FROM "test";