图数据库
GraphView使用一个SQL数据库来管理图数据。GraphView使用SQL连接字符串连接到一个已有的SQL数据库,并且未提供任何额外的API来管理数据库。所有对数据库的管理,比如设置数据库属性或者管理用户账户,都仍然使用SQL Server Management Studio并基于T-SQL语句进行管理。
GraphView使用SQL已有的对象,比如表、索引、用户定义的功能来进行对所有数据和元数据的管理。只要用户有足够的权限,这些对象都是对SQL用户可见的。作为一个中间件,GraphView并未防止你绕过GraphView来对这些对象进行修改。然而,建议使用复制、备份之类的对整体数据进行的操作,而不是单独的对某个对象进行修改,否则将导致GraphView无法修复的数据损坏。
打开/关闭数据库
可以用GraphViewConnection对象打开一个图数据库。GraphViewConnection是一个使用SQL数据库连接字符串实例化的类,就像SqlConnection一样。
using GraphView;
……
string connectionString = “DataSource=(local);Initial Catalog=GraphTesting;Integrated Security=true;”;
GraphViewConnection gdb = newGraphViewConnection(connectionString);
try {
// 连接一个数据库,如果GraphView必须的对象不存在,就创建它们
gdb.Open(true);
}
catch(DatabaseException e) {
// 异常处理
}
当连接字符串指向的是微软云AzureSQL 数据库实例时,使用以下代码:
using GraphView;
……
var sqlConnectionBuilder = newSqlConnectionStringBuilder();
sqlConnectionBuilder["Server"] =
"tcp:graphview.database.windows.net,1433";
sqlConnectionBuilder[“User ID”] = “xxx”;
sqlConnectionBuilder[“Password”] = “xxx”;
sqlConnectionBuilder[“Database”] =“GraphTesting”;
GraphViewConnection gdb =
new GraphViewConnection(connectionString);
try {
// Connects to a database. Creates objects neededby
// GraphViewif they do not exist.
gdb.Open(true);
}
catch(DatabaseException e) {
// Exception handling goes here
}
SQL数据库必须设置为CLR-enabled才可以被GraphView连接。对于Azure SQL数据库(V12或以上版本),CLR自动已经设置为可用。对于SQL Server,需要数据库管理员把CLR设置为enabled。代码如下:
sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'clr enabled', 1;
GO
RECONFIGURE;
GO
GraphView在SQL数据库中维护了一批SQL对象用来管理图的数据和元数据。当一个图数据库打开的时候,GraphView自动检查这些对象是否存在。遇到对象不存在的情况,如果Open()被设置为true,GraphView会自动创建这些对象,否则就会抛出一个DatabaseException的错误。
可以通过GraphViewConnection.Close()或GraphViewConnection.Dispose()来关闭数据库连接。这个方法在内部关闭实例的SqlConnection连接。在非正常情况下,也可以通过调用GraphViewConnection.Close()来实现此行为/结果。对于数据库实例而言,连接关闭的时,所有未提交的变更都将丢失。而且已关闭的连接将被丢失,无法再次开启。必须新建一个图数据库连接的实例。
using GraphView;
……
GraphViewConnectiongdb =
new GraphViewConnection(connectionString);
try {
gdb.Open(true);
// Data manipulations go here
gdb.Close();
}
catch(DatabaseException e) {
// Exception handling goes here
}
创建节点类型(节点表)
图是由节点和边组成的,每个节点或边都关联着一个或多个属性。在GraphView中,需要创建“节点类型”来定义图。一个节点类型类似于一张表,用于指定图包含的节点集的格式,它包括了节点属性和用于连接各类节点的边(也可用于连接自己)。每个节点实例就相当于数据表中的符合特定格式/定义/类型的一行。在本手册中,“节点类型”和“节点表”基本是等价的。
节点类型用CREATE TABLE语句来创建。语法和标准SQL基本类似,唯一不同的是,每个字段都有一个“注释”用于定义字段的类型是节点的属性还是边的列表。
邻接表中的每一项不仅包含被指向节点的信息,同时也包括边本身的属性。邻接表是一个存储节点指向其他节点的边的集合。
邻接表用于声明此节点指向周围节点的所有边的集合,同时也包含了边的属性。当一个字段被声明为邻接表时,它需要描述哪一种类型的节点被这些边所指向,以及边的属性。就其本身而言,CREATE TABLE语句定义了节点和相应的边。
CREATE TABLE EmployeeNode (
[ColumnRole:”NodeId”]
WorkId varchar(32),
[ColumnRole:”Property”]
Name varchar(32),
[ColumnRole:”Edge”, Reference:”EmployeeNode”]
Colleagues VARBINARY,
[ColumnRole:”Edge”, Reference:”ClientNode”, Attributes:{credit:”int”, note:”string”}]
Clients VARBINARY
)
上述的语句定义了EmployeeNode节点。和传统的CREATE Table语句相比,每一个字段(列)均被注释所定义。标准的巴科斯-诺尔范式语法语句表达式如下:
<column_annotation>::=
‘[’ColumnRole:[ NODEID | PROPERTY | EDGE ],
[ Reference: sink_table,
[ Attributes: {property_name: “property_type”[, … n ] } ]
]
‘]’
在注释中,ColumnRole 定义了一个字段,字段的值是在NODEID|PROPERTY|EDGE中三选一。NodeID相当于SQL里的主键,可以用于唯一标识一个节点实例。就像主键一样,它是一个节点类型的可选项。如果一个节点不包含主键,需要用其他的查询方式来查找一个节点,并且无法保证结果集是唯一的(单元素集)。
当ColumnRole的值是Edge的时候,字段值是一个邻接表,邻接表是一种标准的用于描述图的拓扑结构的数据结构。邻接表是一个列表,它的每个元素都代表一个指向邻接节点的边。这个字段的数据类型永远是varbinary。在注释里,ColumnRole后边是引用(Reference),引用定义了边指向的节点的类型。换言之,引用的值是由另一个CREATE TABLE语句定义的节点类型。在以上的例子中,Colleagues和Client两个字段被定义为边,它代表了分别指向EmployeeNode和ClientNode两个节点实例的两个列表。
在Reference之后是Attributes,Attributes是一个可以定义边属性的可选项。边属性是由一对名字和数据类型形成的组合。在这个样例里,Colleagues字段没有注释,所以Colleagues边是没有属性的。而另一方面说,Clients字段是带有属性的,并且列表中的每条边都带有“credit”和“note”两个属性。“credit”是int型而“note”是“string”型。现在,节点的属性可以是任何SQL Server能够支持的类型,并且边属性可以是以下中的一种:int,long,float,double,string
为了执行CREATE TABLE语句,需要调用GraphViewConnection.CreateNodeTable()方法。
usingGraphView;
……
try{
gdb.Open(true);
stringcreateNodeSt = “CREATE TABLE EmployeeNode(……)”;
gdb.CreateNodeTable(createNodeSt);
gdb.Close();
}
catch(DatabaseExceptione) {
//Exception handling goes here
}
这是一个事务性的调用。一旦返回,GraphView将在数据库中创建比如表、用户定义功能等必要的SQL对象。如果返回了错误,比如没有创建SQL对象的权限,将会抛出一个错误信,并且GraphView不会在SQL Server中留下任何记录。
删除节点表
删除节点表使用DROP TABLE的语句:
usingGraphView;
……
try{
gdb.Open(true);
gdb.CreateNodeTable(“DROPTABLE EmployeeNode”);
gdb.Close();
}
catch(DatabaseExceptione) {
//Exception handling goes here
}
DROP TABLE语句只有在一种情况下会被成功执行,那就是在整个图中,没有别的任何一条边指向本表中的任何节点实例的情况下。这个约束保证了图永远是健康的,而且没有边会指向一个不存在的幽灵节点。如果仍然有指向本表的边存在,必须使用DELETE EDGE语句(下文中会详细介绍)删除之后才能成功删除表。