定义一个图模型(Graph Schema)

在数据被加载到图形中之前,用户需首先定义该图的图模型;图模型(Graph Schema)就像一本字典一样,定义了图形中的各种实体(顶点)的类型以及它们之间的关系。下图中,圆圈代表顶点类,线段代表了边类。圆圈中的字标明了它们类型的名称。示例中包括了四种类型的顶点类:User、Occupation、Book以及Genre,还包括了三种边类:user_occupation, user_book_rating和book_genre。 请注意,这张图并没有告诉你这个图数据库中囊括了多少个读者或书本,也没有告诉你相关的关系样本的基数。例如,它没有标明一个User是否关联多个职业Occupation。

每条边连接两个顶点;在TigerGraph中我们分别叫他们起始顶点(source vertex)和目标顶点(target vertex)。一条边的类型可以是有向型(directed)或无向型(undirected)。一条有向型的边拥有清晰的指向,从起始顶点指向目标顶点。例如,假设有某一种类型的边用来表示飞机的航线,则每条航线都必须明确拥有出发地(起始顶点)和目的地(目标顶点)。而在下面示例中,所有的边类型都是无向型边。用一个简单的测试就可以用来判断一条边是有向型还是无向型:如果知道从A可以通向B,并不能判断是否也能从B通向到A,则该边为有向型边。例如,即使我们知道从芝加哥到上海有直飞航班,也不能判定从上海飞芝加哥也有直飞航班。

图1- 用户图书评分系统(User-Book-Rating)的图数据库纲目

下图是一个扩展版本的图模型,除了包含之前的顶点和边类型以外,还添加了额外三种边类型:friend_of, sequel_of 和 user_book_read。请注意,friend_of连接了两个User。由于友谊关系是双向的,所以这是一种无向型边。sequel_of连接了Book与Book,但它是一种有向型边,由图中箭头表示。 例如《指环王·双塔奇兵》《指环王·护戒使者》的续作,反过来则不成立。user_book_read则显示出一对顶点类型之间可能存在多个边类型。

图2 – 增加额外边后的扩充版用户书籍评分图数据库纲目

TigerGraph系统的开发者通过设计图数据库纲目来展示源数据中用户的需求和兴趣。开发者需要考虑用户不同兴趣之间的关系,以及如何分析他们的需求。任何现存的图数据库纲目都是可以被随时修改的,所以用户不会被初始设计所束缚。

在图1中一共有七个实体:4个顶点类和3个边类。你可能希望知道为什么我们将Occupation设定为一个单独的顶点类,而不是将它设定为User的一个属性。类似地,为什么将Genre设定为一个顶点类,而不是Book的一个属性?这些示例都是在初始设计时就已经设定好了的。 Occupation和Genre之所以被单独设计成顶点类,是因为在后续的图查询中,设计成类会更加便于查询。

当开发者完成图数据库纲目的设计,则该该框架便随时能够形成一系列的GSQL语句。

创建和修改图模型的权限

只有超级用户(superuser)可以通过CREATE VERTEX / EDGE / GRAPH命令来定义全局顶点类,全局边类以及图。然而,一旦该图形已被建立,则管理员(admin)和设计者(designer)用户也可以通过SCHEMA_CHANGE JOB命令修改该图数据库纲目,比如添加新的局部顶点类和局部边类。下一章节会详细介绍此内容。

建立顶点

仅适用于超级用户.

CREATE VERTEX语句定义一个全新的全局顶点类,包含一个类名和对应的属性列表。其命令格式为:

CREATE VERTEX vertex_type_name (PRIMARY_ID id type [,attribute_list]) [ vertex_options ]:

具体句法如下:

CREATE VERTEX的语法规则:
CREATE VERTEX vertex_type_name (PRIMARY_ID id_name type
      [, attribute_name type [DEFAULT default_value] ]*)
      [WITH STATS="none"|"outdegree_by_edgetype"]

PRIMARY_ID

Primary_ID 是必须项,它是用于区分顶点实例身份的唯一标示。只有设定为两种数据类型:STRING或UINT

顶点属性列表

方括号中的内容为属性列表,是由逗号分隔,包含一个或多个身份标识定义(id definition)和属性描述(attribute description):

(PRIMARY_ID id_name type , 
[ attribute_name type [DEFAULT default_value ] ]*)
  1. 开头的PRIMARY_ID id type 是必须项,其中id是标识符,type指定属性的数据类型,具体在“语言基础”一章中详述。

  1. 每个属性的数据类型都有一个内建的默认值(例如,INT类的默认值就是0)。使用DEFAULT default_value 指定正确的值,并覆盖默认值。

  2. 对于id的属性来说,其后可以列出任意数量的附加属性。 每个属性都有一个名称,类型和可选的默认值(仅适用于primitive-type,DATETIME或STRING COMPRESS属性)

例:

  • 为图1 的图数据库纲目创建顶点类

用户书籍评分系统图的顶点定义
CREATE VERTEX User (PRIMARY_ID user_id UINT, name STRING, age UINT, gender STRING, postalCode STRING)
CREATE VERTEX Occupation (PRIMARY_ID occ_id UINT, occ_name STRING)
   WITH STATS="outdegree_by_edgetype"
CREATE VERTEX Book  (PRIMARY_ID bookcode UINT, title STRING, pub_year UINT)
   WITH STATS="none"
CREATE VERTEX Genre (PRIMARY_ID genre_id STRING, genre_name STRING)

不同于关系型数据库中的表,在图数据库中,一个顶点类并不需要一个外部键(foreign key)属性来与另一个顶点类相关联,这样的关联是通过边类来实现的。

WITH STATS选项

默认情况下,当加载器将一个顶点及其属性存储在图数据库中时,它还同时存储相关顶点的一些外部指数(outdegree) --- 即该顶点与其他顶点的连接数。 可选的WITH STATS子句选项可以让用户自行控制需要记录的数据量。 将WITH STATS获取的记录数据存储在图数据库中,会在查询需要外部指数的时候增加查询速度,但同时它也会增加内存占用。 该选项有两个*选择。 如果选择“outdegree_by_edgetype”,则每个顶点记录一系列外部指数计数值(degree count value),图数据库纲目中的每个边类对应一个值。 如果选择“none”,则不会记录每个顶点的外部指数统计。 如果附加WITH STATS子句,则加载器默认按照选择“outdegree_by_edgetype”的方式运行。

例:如果外部指数信息已被记录,则可以通过outdegree()函数进行查询调用

下图中,在人与人之间有两种边:phone_call和text。对于Bobby来说,"outdegree_by_edgetype"的选项记录了Bobby打过多少电话(1)和发过多少短信(2)。通过内建函数outdegree()可以获得这些数据。若想只针对某个特定的边类获得对应的数据,则需要以字符串形式声明要查找的对应边类的名称。如果只想知道总数,就不需要添加该参数。

图3 – 外部指数的概念

WITH STATS选项

(大小写明显)

Bobby.outdegree()

Bobby.outdegree("text")

Bobby.outdegree("phone_call")

"none"

不适用

不适用

不适用

"outdegree_by_edgetype" (默认值)

3

2

1

创建边

仅超级用户适用

通过CREATE EDGE语句可以定义一个全新的全局边类。 CREATE EDGE语句有两种形式,一种用于有向边,另一种用于无向边。 每个边类必须指定一个起始顶点类,并连接到一个目标顶点类。 创建边类的同时可以添加其他属性。 每个属性都遵循与“创建顶点-属性列表”章节中描述的相同要求。

创建无向型边
CREATE UNDIRECTED EDGE edge_type_name (FROM vertex_type_name, TO vertex_type_name
 [, attribute_name type [DEFAULT default_value]]* )
创建有向型边
CREATE DIRECTED EDGE edge_type_name (FROM vertex_type_name, TO vertex_type_name
 [, attribute_name type [DEFAULT default_value]]* )
 [WITH REVERSE_EDGE="rev_name"]

高度抽象后的格式如下:

CREATE UNDIRECTED|DIRECTED EDGE edge_type_name (FROM vertex_type_name , TO vertex_type_name , 
edge_attribute_list ) [ edge_options ]

注意:这样建立的边并不包含PRIMARY_ID。每条边由一个FROM顶点和一个TO顶点来定义唯一,其他属性则为可选项。边类也可以用来区分不同的边。例如上面的图2中,在User和Book之间有两个不同的边类,但它们都有以(FROM User, To Book,...)开始的属性列表。

一个边类可以被定义为从任意顶点类开始(FROM),并指向(TO)任何顶点类。可以使用通配符*来表示任意顶点类。例如,下面例子中的边类any_edge 可以从任何顶点指向任何顶点。

用通配符表示任意边类
CREATE DIRECTED EDGE any_edge (FROM *, TO *, label STRING)

REVERSE_EDGE参数

如果声明CREATE DIRECTED EDGE时同时声明了参数WITH REVERSE_EDGE=" rev_name ",则一个额外的有向型边" rev_name "会自动生成。该边的起点与终点与原始创建边相反。之后,每当一个新的边生成,就会自动生成一个反向的边。反向的边拥有与原始边相同的属性。同时,当原始的边有变更时,对应反向的边也同时会变更。

在TigerGraph系统中,反向的边可以大幅增加图查询的效率,特别是需要回溯的查询。例如,在图2中的图数据库纲目中,“如果书X有续作,那它的续作是什么?”是一个正向查询。 然而, 当该查询变成“书X是续作吗?如果是的话它的前作是什么?”,那么此时就需要反向查询。

例:

在图1中对三种边类创建无向型边。

在用户图书评分图中的边定义
CREATE UNDIRECTED EDGE user_occupation (FROM User, TO Occupation)
CREATE UNDIRECTED EDGE book_genre (FROM Book, TO Genre)
CREATE UNDIRECTED EDGE user_book_rating (FROM User, TO Book, rating UINT, date_time UINT) 

对于边user_occupation 和边book_genre 来说,它们没有属性值。每一条user_book_rating 边表示用户已经给某本书打过分。因此,它包含一个额外的属性rating 。在这个例子中,rating 属性定义为一个整数值,不过它也可以很容易地被修改成浮点值。

例:

在图2中,创建额外的边

在扩展用户图书评分图中额外的边定义
CREATE UNDIRECTED EDGE friend_of (FROM User, TO User, on_date UINT)
CREATE UNDIRECTED EDGE user_book_read (FROM User, To Book, on_date UINT)
CREATE DIRECTED EDGE sequel_of (FROM Book, TO Book) WITH REVERSE_EDGE="preceded_by"

每当GSQL 加载器创建一个sequel_of 边时,它会同时创建一个反向的preceded_by 边。

特别选项

共用压缩字典(Compression Dictionary)

数据类型STRING COMPRESS和STRING_SET COMPRESS通过将唯一的属性值指向一个小整数来实现数据压缩。对应的映射表("this string" = "this integer") 被称作字典。如果两个属性拥有相同或类似的一组可能的值,则可以使它们共享同一个字典来减少对存储空间的占用。

当STRING COMPRESS属性在顶点或边中声明后,开发者可以选择为其添加一个字典名。任何共享同一个字典名的属性将会共享同一个字典。下面的例子中,v1.attr1、v1.attr2和 e.attr1共享同一个名叫e1的字典。

共享 STRING COMPRESS 字典
CREATE VERTEX v1 (PRIMARY_ID main_id STRING, att1 STRING COMPRESS e1, att2 STRING COMPRESS e1)
CREATE UNDIRECTED EDGE e (FROM v1, TO v2, att1 STRING COMPRESS e1)

图的创建

多图支持

仅适用于超级用户

如果选用了可选的多图服务(MultiGraph service),则可以多次引用CREATE GRAPH来定义多个图,顶点类型和边类型在多个图中重复使用(共享)。同时,也可以选择为新生成的图定义管理员。

当所有必要的顶点类和边类都创建完成后,CREATE GRAPH会定义一个图数据库纲目,之前已定义的顶点类和边类会包含在内。这样,该图数据库就可以正式准备接受数据导入。顶点类和边类可以按照任何顺序列出。

CREATE GRAPH 语法
CREATE GRAPH gname (vertex_or_edge_type, vertex_or_edge_type...) [WITH ADMIN username]

可选的WITH ADMIN子句用以将一个已经存在的用户定义为新建图的管理员。

为了方便起见,执行语句CREATE GRAPH可以将新创建的图直接设置为工作图(working graph)。

如果不希望指定一系列的顶点类和边类,也可以直接定义包含可用顶点类和边类的图类。创建一个空域图的操作也是合法的,并可以通过SCHEMA_CHANGE命令在未来给该空图添加顶点类和边类。

例:通过CREATE GRAPH创建包括所有顶点类和边类的图和空域图
CREATE GRAPH everythingGraph (*)
CREATE GRAPH emptyGraph ()

例:

基于图1中的顶点类和边类,创建新图Book_rating:

用户图书评分图的创建
CREATE GRAPH Book_rating (*)

下面的代码示例,完整地展示了建立扩展版用户书籍评分图的过程。

建立扩展版用户书籍评分图的完整过程
CREATE VERTEX User (PRIMARY_ID user_id UINT, name STRING, age UINT, gender STRING, postalCode STRING)
CREATE VERTEX Occupation (PRIMARY_ID occ_id UINT, occ_name STRING)
   WITH STATS="outdegree_by_edgetype"
CREATE VERTEX Book  (PRIMARY_ID bookcode UINT, title STRING, pub_year UINT)
   WITH STATS="none"
CREATE VERTEX Genre (PRIMARY_ID genre_id STRING, genre_name STRING)
CREATE UNDIRECTED EDGE user_occupation (FROM User, TO Occupation)
CREATE UNDIRECTED EDGE book_genre (FROM Book, TO Genre)
CREATE UNDIRECTED EDGE user_book_rating (FROM User, TO Book, rating UINT, date_time UINT)
CREATE UNDIRECTED EDGE friend_of (FROM User, TO User, on_date UINT)
CREATE UNDIRECTED EDGE user_book_read (FROM User, To Book, on_date UINT)
CREATE DIRECTED EDGE sequel_of (FROM Book, TO Book) WITH REVERSE_EDGE="preceded_by"
CREATE GRAPH Book_rating (*)

图的使用

本文针对多图支持的新需求所编写,但对于仅有一个图的情况也适用。

在用户使用图数据库之前,首先,必须由管理员或超级用户给该用户赋予一个权限(超级用户自动成为所有图的管理员)。其次,对于每个GSQL的会话,该用户必须指定工作图(working graph)。通过USE GRAPH命令可以在当前会话中设定工作图。

更多有关用户身份和权限的问题,请参见文档Managing User Privileges and Authentication v2.1

USE GRAPH 语法
USE GRAPH gname

除了可以使用USE GRAPH命令之外,也可以采用附带-g <graph_name>选项调用gsql的方式

删除图

仅适用于超级用户。基于共享域的考量,该命令的效果已被调整。

DROP GRAPH 语法
DROP GRAPH gname

DROP GRAPH命令会删除指定的某个图中的所有逻辑对象。此外,任何一个不与其他图共享的顶点类和边类以及它们对应的数据都会被删除。但如果该类与其它的图共享,则该类不会被删除。如果只是想删除某个指定的边类或顶点类,请参看“修改图模型”章节中的DROP VERTEX | EDGE命令。

Last updated

Was this helpful?