图数据库
2021-07-14 14:39:09 0 举报
AI智能生成
nebulagraph图数据的相关知识店
作者其他创作
大纲/内容
NebulaGraph
数据结构
space(图空间)
不同图空间的数据是相互隔离的,可以指定不同的存储副本数、权限、分片等
tag(标签)
点的类型,定义了一组描述点类型的属性
edge type(边类型)
边的类型,定义了一组描述边类型的属性
vertex(点)
点是用点标识符( VID )标识的
VID 在同一图空间中唯一
VID 是一个 int64, 或者 fixed_string(N)
必须有至少一个标签(Tag),也可以有多个标签
存储格式
Type key类型
PartID 数据分片编号
VertexID 点ID
TagID 点关联的标签ID
edge(边)
四元组 <起点VID、边类型(edge type)、边排序值(rank)、终点VID> 用于唯一标识一条边
存储格式
Type key类型
PartID 数据分片编号
VertexID 点ID
Edge Type 边的类型
Rank
用来处理两点之间有多个同类型边的情况
PlaceHolder 占位符
数据类型
数值类型
int (64位)
double
bool
true
false
字符串
string
fixed_string(length)
日期类型
date
time
datetime
timestamp
使用示例
CREATE TAG date1(p1 date, p2 time, p3 datetime);
INSERT VERTEX date1(p1, p2, p3) VALUES "test1":(date("2021-03-17"), time("17:53:59"), datetime("2021-03-17T17:53:59"));
CREATE TAG school(name string , found_time timestamp);
INSERT VERTEX school(name, found_time) VALUES "DUT":("DUT", 573206400);
INSERT VERTEX school(name, found_time) VALUES "DUT":("DUT", timestamp("1988-03-01T08:00:00"));
架构
graph service
处理查询请求
端口
9669:rpc服务端口
19669:http服务端口
19670:http2服务端口
storage service
数据存储
类似kafka分区,只有各分片的leader副本提供读写服务
扩容后,需要手动执行BALANCE DATA负载均衡数据
缩容,手动执行BALANCE DATA REMOVE <host_list> 移除服务
BALANCE DATA 只能均衡分片分布,不能均衡Raft leader分布
可以使用命令 BALANCE LEADER 均衡leader分布
端口
9779:rpc对外服务端口
9777、9778、9780:rpc服务内部端口,多副本间交互
19779:http服务端口
19780:http2服务端口
meta service
主从集群架构,只有leader能够对客户端或其他组件提供服务
用户权限管理
Schema操作
集群管理
图空间
分片
分片策略采用静态 Hash的方式,即对点ID进行取模操作,同一个点的所有标签、出边和入边信息都会存储到同一个分片
TTL数据回收
管理作业
SUBMIT JOB COMPACT语句 会触发RocksDB的长耗时 compact
SUBMIT JOB FLUSH 语句将内存中的RocksDB memfile写入硬盘
SUBMIT JOB STATS 语句启动一个作业,该作业对当前图空间进行统计
不支持在线扩缩容,也不支持迁移到新机器,主要是未提供相关的命令
不支持事务操作
端口
9559:rpc对外服务端口
9560:rpc服务内部端口,多副本间交互
19560:http2服务端口
分支主题
nGQL
创建图空间
CREATE SPACE [IF NOT EXISTS] <graph_space_name>
[(partition_num = <partition_number>, replica_factor = <replica_number>, vid_type = {FIXED_STRING(<N>) | INT64})];
不指定参数,默认partition_num=100、replica_factor =1、vid_type=FIXED_STRING(8)
CREATE SPACE basketballplayer(partition_num=15, replica_factor=1, vid_type=fixed_string(30));
创建标签和边类型
CREATE {TAG | EDGE} {<tag_name> | <edge_type>}
(<property_name> <data_type>[, <property_name> <data_type> ...]);
CREATE TAG player(name string, age int);
CREATE EDGE follow(degree int);
点操作
插入点
INSERT VERTEX <tag_name> (<property_name>[, <property_name>...])[, <tag_name> (<property_name>[, <property_name>...]), ...]{VALUES | VALUE}
<vid>: (<property_value>[, <property_value>...])[, <vid>: (<property_value>[, <property_value>...];
INSERT VERTEX player(name, age) VALUES "player100":("Tim Duncan", 42);
删除点
DELETE VERTEX <vid1>[, <vid2>...]
DELETE VERTEX "player100"
更新点
UPDATE VERTEX ON <tag_name> <vid>
SET <update_prop>
[WHEN <condition>]
[YIELD <output>]
UPDATE VERTEX "player100" SET player.name = "Tim";
UPDATE VERTEX ON player "player101"
SET age = age + 2
WHEN name == "Tony Parker"
YIELD name AS Name, age AS Age;
边操作
插入边
INSERT EDGE <edge_type> (<property_name>[, <property_name>...])
{VALUES | VALUE} <src_vid> -> <dst_vid>[@<rank>] : (<property_value>[, <property_value>...])
[, <src_vid> -> <dst_vid>[@<rank>] : (<property_name>[, <property_name>...]), ...];
INSERT EDGE follow(degree) VALUES "player100" -> "player101":(95);
删除边
DELETE EDGE <edge_type> <src_vid> -> <dst_vid>[@<rank>]
[, <edge_type> <src_vid> -> <dst_vid>[@<rank>] ...]
DELETE EDGE follow "team1" -> "team2";
更新边
UPDATE EDGE ON <edge_type>
<src_vid> -> <dst_vid> [@<rank>]
SET <update_prop>
[WHEN <condition>]
[YIELD <output>]
UPDATE EDGE on serve "player100" -> "team204"@0
SET start_year = start_year + 1
WHEN end_year > 2010
YIELD start_year, end_year;
查询数据
GO 根据条件遍历数据库
GO [[<M> TO] <N> STEPS ] FROM <vertex_list>
OVER <edge_type_list> [{REVERSELY | BIDIRECT}]
[ WHERE <conditions> ]
[YIELD [DISTINCT] <return_list>]
[| ORDER BY <expression> [{ASC | DESC}]]
[| LIMIT [<offset_value>,] <number_rows>]
引用符
$^ 表示起始点
$$ 表示目的点
$- 引用复合查询中管道符之前的语句输出结果
边的内置属性
_src 边的起始点
_dst 边的目的点
_type 边的类型内部编码,正负号表示方向
_rank 边的rank值
REVERSELY | BIDIRECT :默认情况下检索的是 <vertex_list> 的出边, REVERSELY 表示反向,即检索入边, BIDIRECT 表示双向,即检索出边和入边
GO [[<M> TO] <N> STEPS ] FROM <vertex_list>
OVER <edge_type_list> [{REVERSELY | BIDIRECT}]
[ WHERE <conditions> ]
[| GROUP BY {col_name | expr | position} YIELD <col_name>]
GO FROM "player100" OVER follow; //从VID为 player100 的球员开始,沿着边 follow 找到连接的球员
GO FROM "player100" OVER follow REVERSELY YIELD follow._dst AS destination; //返回player100的入边
GO FROM "player100" OVER follow WHERE $$.player.age >= 35 YIELD $$.player.name AS Teammate, $$.player.age AS Age;
GO FROM "player100" OVER follow YIELD follow._dst AS id | GO FROM $-.id OVER serve YIELD $$.team.name AS Team, $^.player.name AS Player;
GO 1 TO 2 STEPS FROM "player100" OVER follow YIELD follow._dst AS destination; //查询player100 1~2跳内的朋友
GO 2 STEPS FROM "player100" OVER follow
YIELD follow._src AS src, follow._dst AS dst, $$.player.age AS age
| GROUP BY $-.dst
YIELD $-.dst AS dst, collect_set($-.src) AS src, collect($-.age) AS age //根据年龄分组
GO FROM "player100" OVER follow REVERSELY
YIELD $$.player.name AS Friend, $$.player.age AS Age
| ORDER BY Age,Friend
| LIMIT 1, 3; //从排序结果中返回第2行开始的3行数据
FETCH语句可以获得点或边的属性
查询标签属性
FETCH PROP ON {<tag_name> |<tag_name_list> | *} <vid_list>
[YIELD [DISTINCT] <return_list>];
FETCH PROP ON player "player100";
查询边属性
FETCH PROP ON <edge_type> <src_vid> -> dst_vid>[@<rank>][, <src_vid> -> <dst_vid> ...]
[YIELD [DISTINCT] <return_list>];
FETCH PROP ON serve "player100" -> "team204";
FETCH PROP ON serve "player100" -> "team204"@1;
LOOKUP语句是基于索引的,查找符合特定条件的数据
LOOKUP ON {<tag_name> | <edge_type>}WHERE <expression> [AND expression ...])]
[YIELD <return_list>];
LOOKUP ON player WHERE player.name == "Tony Parker" YIELD player.name, player.age;
不支持
$- 和 $^
在关系表达式中,不支持运算符两边都有字段名,例如 tagName.prop1> tagName.prop2
不支持运算表达式和函数表达式中嵌套AliasProp表达式
不支持 starts with ends with contains 等字符串索引模糊查询操作
不支持 OR 和 XOR 运算符
GET SUBGRAPH获取子图信息
GET SUBGRAPH [<step_count> STEPS] FROM {<vid>, <vid>...}
[IN <edge_type>, <edge_type>...]
[OUT <edge_type>, <edge_type>...]
[BOTH <edge_type>, <edge_type>...];
GET SUBGRAPH 1 STEPS FROM "player100";
GET SUBGRAPH 1 STEPS FROM "player100" OUT serve;
FIND PATH 查找指定起始点和目的点之间的路径
FIND { SHORTEST | ALL | NOLOOP } PATH
FROM <vertex_id_list> TO <vertex_id_list>
OVER <edge_type_list> [REVERSELY | BIDIRECT]
[UPTO <N> STEPS] [| ORDER BY $-.path] [| LIMIT <M>];
SHORTEST :查找最短路径
ALL :查找所有路径
NOLOOP :查找非循环路径
FIND SHORTEST PATH FROM "team200" TO "player100" OVER * REVERSELY
字句和选项
YIELD
定义nGQL查询的输出结果
YIELD [DISTINCT] <col> [AS <alias>] [, <col> [AS <alias>] ...];
YIELD [DISTINCT] <col> [AS <alias>] [, <col> [AS <alias>] ...]
[WHERE <conditions>];
集合运算符
UNION
返回两个集合的并集
<left> UNION [DISTINCT | ALL] <right> [ UNION [DISTINCT | ALL] <right> ...]
GO FROM "player102" OVER follow
YIELD follow._dst AS id, follow.degree AS Degree, $$.player.age AS Age
UNION /* DISTINCT */
GO FROM "player100" OVER follow
YIELD follow._dst AS id, follow.degree AS Degree, $$.player.age AS Age;
INTERSECT
返回集合的交集
GO FROM "player102" OVER follow
YIELD follow._dst AS id, follow.degree AS Degree, $$.player.age AS Age
INTERSECT
GO FROM "player100" OVER follow
YIELD follow._dst AS id, follow.degree AS Degree, $$.player.age AS Age;
MINUS
返回集合的差集
GO FROM "player100" OVER follow
MINUS
GO FROM "player102" OVER follow;
字符运算符
CONTAINS 在字符串中执行搜索。
(NOT) IN 字符串是否匹配某个值。
(NOT) STARTS WITH 在字符串的开头执行匹配。
(NOT) ENDS WITH 在字符串的结尾执行匹配。
正则表达式 通过正则表达式匹配字符串
仅openCypher语句(MATCH 、 WITH 等)支持正则表达式
nGQL扩展语句( FETCH 、 GO 、 LOOKUP 等)暂不支持正则表达式
索引
CREATE {TAG | EDGE} INDEX [IF NOT EXISTS] <index_name>
ON {<tag_name> | <edge_name>} (prop_name_list);
CREATE TAG INDEX player_index_0 on player(name(20));
REBUILD TAG INDEX player_index_0;
查看修改配置
SHOW CONFIGS
关闭自动compact
UPDATE CONFIGS storage:rocksdb_column_family_options = {disable_auto_compactions: true, max_bytes_for_level_base: 268435456, max_write_buffer_number: 4, write_buffer_size:
67108864};
cypher
MATCH语句依赖索引去匹配数据
MATCH <pattern> [<WHERE clause>] RETURN <output>;
节点由圆括号表示,看起来像是圆圈。就像这样:(node)
关系用箭头来表示。像这样: ->,只有 - 时表示双向关系
关系相关的信息可以插入到方括号中。像这样:[:KNOWS]
pattern模式
(a)
(a)-[]->(b)
(a)-[]->(b)<-[]-(c
(a:User)-[]->(b)
(a:User:Admin)-[]->(b)
(a {name: 'Andres', sport: 'Brazilian Ju-Jitsu'})
(a)-[{blocked: false}]->(b)
(a)-[r]->(b)
(a)-[r:REL_TYPE]->(b)
(a)-[r:TYPE1|TYPE2]->(b)
(a)-[:REL_TYPE]->(b)
(a)-[*2]->(b)
(a)-[*3..5]->(b)
(a)-[*..5]->(b)
WITH
WITH 子句可以获取并处理查询前半部分的结果,并将处理结果作为输入传递给查询的后半部分
MATCH (v:player)-->(v2:player)
WITH DISTINCT v2 AS v2, v2.age AS Age
ORDER BY Age
WHERE Age<25
RETURN v2.name AS Name, Age;
常用函数
id(vertex) 返回点ID
tags(vertex) 返回点的标签
properties(vertex_or_edge) 接收点或边并返回其属性
type(edge) 返回边的边类型。
startNode(path) 获取一条边或一条路径并返回它的起始点ID
string endNode(path) 获取一条边或一条路径并返回它的目的点ID
rank(edge) 返回边的rank
MATCH (v:player{name:"Tony Parker"}) RETURN v;
MATCH (v:player{name:"Tim Duncan"})-->(v2)<--(v3) RETURN v3.name AS Name;
MATCH p=(v:player{name:"Tim Duncan"})-->(v2) RETURN p;
MATCH (v:player{name:"Tim Duncan"})-[e:follow|:serve]->(v2) RETURN e;
MATCH p=(v:player{name:"Tim Duncan"})-[e:follow*2]->(v2) RETURN DISTINCT v2 AS Friends;
MATCH p=(v:player{name:"Tim Duncan"})-[e:follow*1..3]->(v2) RETURN v2 AS Friends;
MATCH p=(v:player{name:"Tim Duncan"})-[e:follow|serve*2]->(v2) RETURN DISTINCT v2;
MATCH p=(v:player{name:"Tim Duncan"})-[]->(v2) RETURN nodes(p);
MATCH p=(v:player{name:"Tim Duncan"})-[]->(v2) RETURN relationships(p);
权限管理
用户管理
创建用户
CREATE USER [IF NOT EXISTS] <user_name> [WITH PASSWORD '<password>'];
CREATE USER user1 WITH PASSWORD 'nebula';
删除用户
DROP USER [IF EXISTS] <user_name>;
DROP USER user1;
修改用户密码
CHANGE PASSWORD <user_name> FROM '<old_password>' TO '<new_password>';
CHANGE PASSWORD user1 FROM 'nebula' TO 'nebula123';
授权用户
GRANT ROLE <role_type> ON <space_name> TO <user_name>;
GRANT ROLE USER ON basketballplayer TO user1;
撤销用户权限
REVOKE ROLE <role_type> ON <space_name> FROM <user_name>;
REVOKE ROLE USER ON basketballplayer FROM user1;
内置角色
God
初始最高权限角色,拥有所有操作的权限
一个集群只能有一个God角色用户,该用户可以管理集群内所有图空间
Meta服务初始化时,会自动创建God角色用户 root ,密码为 nebula
Admin
对权限内的图空间拥有Schema和data的读写权限
可以将权限内的图空间授权给其他用户
DBA
对权限内的图空间拥有Schema和data的读写权限
无法将权限内的图空间授权给其他用户
User
对权限内的图空间拥有Schema的只读权限
对权限内的图空间拥有data的读写权限
java客户端
只提供类似jdbc的最简单的执行语句功能,未对操作语法进行api封装
第三方jar,neo4j-cypher-dsl提供的match相关的语法api,可以实现cypher语法查询语句的生成
Neo4j
Cypher
查询可以参考nebula的match语法
创建节点
CREATE (
<node-name>:<label-name>
{
<Property1-name>:<Property1-Value>
........
<Propertyn-name>:<Propertyn-Value>
}
)
CREATE (emp:Employee{id:123,name:"Lokesh",sal:35000,deptno:10})
创建关系
现有节点创建关系
MATCH (<node1-label-name>:<node1-name>),(<node2-label-name>:<node2-name>)
CREATE
(<node1-label-name>)-[<relationship-label-name>:<relationship-name>
{<define-properties-list>}]->(<node2-label-name>)
RETURN <relationship-label-name>
MATCH (cust:Customer),(cc:CreditCard)
CREATE (cust)-[r:DO_SHOPPING_WITH{shopdate:"12/12/2014",price:55000}]->(cc)
RETURN r
新节点创建关系
CREATE
(<node1-label-name>:<node1-name>)-
[<relationship-label-name>:<relationship-name>]->
(<node1-label-name>:<node1-name>)
RETURN <relationship-label-name>
CREATE (fb1:FaceBookProfile1)-[like:LIKES]->(fb2:FaceBookProfile2)
社区版不支持集群模式
HugeGraph
gremlin
架构
HugeGraph-Server
Core:图引擎实现,向下连接Backend模块,向上支持API模块
Backend:实现将图数据存储到后端,支持的后端包括:Memory、Cassandra、ScyllaDB、RocksDB、HBase及MySQL
API:内置REST Server,向用户提供RESTful API,同时完全兼容Gremlin查询
不支持集群模式
图查询语法差异
分支主题
0 条评论
下一页