SqlServer图形数据库初体验

摘要:
下面介绍图形表与常用的角色任务操作三层权限管理模型的使用。“任务3')Go每个节点表都有一个伪列$node_id,$node_id的值是json的一部分。您可以看到实际的$node_id字段名后面跟着一个十六进制数字字符串。

  SQL Server2017新增了一个新功能叫做图形数据库。图形指的拓扑图形,是一些Node表和Edge表的合集,Node对应关系数据库中的实体,比如一个人、一个岗位等,Edge表指示Node之前的关系,比如张三在经理岗位。图形表比较适合用来表示这种实体与实体之间有明显关联关系的情况,比如学生和课程,学生是Node表,选课记录是Edge表。下面以比较常用的角色-任务-操作三层权限管理模型说明图形表的使用。

  在SSMS中,可以看到数据库的“表”节点下面有“图形表”这个节点:

  SqlServer图形数据库初体验第1张

  创建图形表的语句与普通表大体相同,只是在语句最后加上AS NODE或AS EDGE,表示创建的是Node表还是Edge表。创建用户、角色、任务、操作四张Node表,并插入一些测试数据:

Create Table Roles
(
    RoleName nvarchar(20) primary key,
	RoleDesc nvarchar(255)
)
As Node
Go

Create Table Tasks
(
	TaskName nvarchar(20) primary key,
	TaskDesc nvarchar(255)
)
As Node
Go

Create Table Opers
(
	OperName nvarchar(20) primary key,
	OperDesc nvarchar(255)
)
As Node
Go

Create Table Users
(
	UserID nvarchar(20) primary key,
	UserName nvarchar(255)
)
As Node
Go
insert into Roles Values('R001','经理')
insert into Roles Values('R002','库管员')
insert into Roles Values('R003','出纳')
Go

Insert into Users Values('U001','张三')
Insert into Users Values('U002','李四')
Insert into Users Values('U003','王五')
Go

Insert into Opers Values('C001','操作1')
Insert into Opers Values('C002','操作2')
Insert into Opers Values('C003','操作3')
Go

Insert into Tasks Values('T001','任务1')
Insert into Tasks Values('T002','任务2')
Insert into Tasks Values('T003','任务3')
Go

  每一个Node表都有一个伪列$node_id,这个列是SQL Server自动添加且自动填充的。$node_id的值是一段json。

SqlServer图形数据库初体验第2张

  可以看到实际上的$node_id字段名后面还有一串16进制数字,查询的时候,使用$node_id作为字段名是可以查询出来的:

SqlServer图形数据库初体验第3张

  反而如果用这个字段的全称$node_id_E42A169EC3FA4F84B5E932FD8B877822,是会报错:Invalid pseudocolumn "$node_id_E42A169EC3FA4F84B5E932FD8B877822".

  在SSMS中查看表结构:

SqlServer图形数据库初体验第4张

  还有一个graph_id列,这个列是数据库内部使用,对我们没有用。 

  再创建表示用户-角色对应关系、角色-任务对应关系、任务-操作对应关系的三张Edge表,并插入数据:

Create Table UserRole As Edge
Go

Create Table RoleTask As Edge
Go

Create Table TaskOper As Edge
Go

Insert into UserRole Values((select $node_id from Users where UserID='U001'),(select $node_id from Roles where RoleName='R001'))
Insert into UserRole Values((select $node_id from Users where UserID='U002'),(select $node_id from Roles where RoleName='R002'))
Insert into UserRole Values((select $node_id from Users where UserID='U003'),(select $node_id from Roles where RoleName='R003'))
Go

Insert into RoleTask Values((select $node_id from Roles where RoleName='R001'),(select $node_id from Tasks where TaskName='T001'))
Insert into RoleTask Values((select $node_id from Roles where RoleName='R002'),(select $node_id from Tasks where TaskName='T002'))
Insert into RoleTask Values((select $node_id from Roles where RoleName='R003'),(select $node_id from Tasks where TaskName='T003'))
Go

Insert into TaskOper Values((select $node_id from Tasks where TaskName='T001'),(select $node_id from Opers where OperName='C001'))
Insert into TaskOper Values((select $node_id from Tasks where TaskName='T001'),(select $node_id from Opers where OperName='C001'))
Insert into TaskOper Values((select $node_id from Tasks where TaskName='T001'),(select $node_id from Opers where OperName='C001'))
Go

  上面创建表并没有写包含任何字段,因为Edge表包含三个默认列:$edge_id、$from_id、$to_id,分别表示记录的id值、第一个Node记录的id、第二个Node记录的id。这样,就表示了两个Node之前有了关联关系。同样的,$edge_id也是自动填充。

  查询角色R001所有的任务:

Select Tasks.TaskName,Tasks.TaskDesc
From Roles,RoleTask,Tasks 
Where Match(Roles-(RoleTask)->Tasks)
And Roles.RoleName='R001'

  SqlServer图形数据库初体验第5张

  Match是图形数据库查询的特有语句,使用Node-(Edge)->Node或Ndoe<-(Edge)-Node来表示Node与Node之间有某种关联。具体语法可以参考https://docs.microsoft.com/en-us/sql/t-sql/queries/match-sql-graph

  查询某个用户的所有操作权限:

Select Opers.OperName,Opers.OperDesc
From Users,UserRole,Roles,RoleTask,Tasks,TaskOper,Opers
Where Match(Users-(UserRole)->Roles-(RoleTask)->Tasks-(TaskOper)->Opers)
And Users.UserID='U001'

  如果用关系型表的方法,就得用类似如下的方法查询:

select Opers.* from Opers join  TaskOper on TaskOper.OperName=Opers.OperName
join RoleTask on RoleTask.TaskName=TaskOper.TaskName
join UserRole on UserRole.RoleName=RoleTask.RoleName
join Users on Users.UserID=UserRole.UserID
where User.UserID='U001'

  可以看到图像表的查询写法更简单一些。

免责声明:文章转载自《SqlServer图形数据库初体验》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇关于谷歌不然安装除商店之外的拓展应用解决linux下导入导出MySQL数据库下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Activiti 常见操作(二)

UEL分配任务 在任务节点设计的时候,assignce设置为${assigneeNum},在启动的时候,把这个变量带上,Activiti就可以动态地设置流程接收人。 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); RuntimeService runtimeSer...

二、Java对返回参数进行处理(JSONObject,getJSONArray等)

一、根据返回参数格式获取其中的值 1.得到ResponseEntity<String> responseEntity对象 import org.springframework.http.ResponseEntity; 得到ResponseEntity<String> responseEntity对象 <200, {...

OneNote无法打开链接出现错误:你的组织策略阻止我们为你完成此操作

首先打开注册表编辑器,按键盘win+r,调出运行窗口,输入regedit打开注册表编辑器 打开HKEY_CURRENT_USERSoftware 打开Classes 最后选中.html,在默认选项那右键点击修改 将里面的数值数据修改成“Htmlfile”,点击确定后退出,重启下电脑,如果不重启电脑,office onenote也要重新打开...

临时表列的长度

创建一个临时表的时候.如果不指定列的长度,则临时表列的长度会根据所参照的表的对应列的大小,如 --创建一个表 Create table tmp1 (tmp1 varchar(3)) --创建临时表select tmp1.tmp1 as tmp2 into #tmp2 from tmp1 --第一条语句成功,但是第二条失败,因为超出了长度 insert in...

了解 yarn 、npm、nodejs

一、前言 针对即将上线的 jeecg-boot 做一些准备。 二、了解系列 1、了解 nodejs Node.js 就是运行在服务端的 JavaScript。 Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。 Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行...

linux 后台执行oracle sql脚本

一、简单后台执行。 nohup  sqlplus   Oracle/Oracle@orcl   @sql.sql     & --这样的写法会报错(Error 45 initializing SQL*Plus Internal error)  今天打算写个后台执行清理单张表和备份sql脚本。发现一直报错,网上也没有具体的修改方法。 后来到别的博客去...