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

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

  

  创建图形表的语句与普通表大体相同,只是在语句最后加上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。

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

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

  在SSMS中查看表结构:

  还有一个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'

  

  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图形数据库初体验的更多相关文章

  1. Net Core平台灵活简单的日志记录框架NLog+SqlServer初体验

    Net Core平台灵活简单的日志记录框架NLog+SqlServer初体验 前几天分享的"[Net Core平台灵活简单的日志记录框架NLog+Mysql组合初体验][http://www ...

  2. SQL Server 全文搜索 配置、查询初体验

    原文:SQL Server 全文搜索 配置.查询初体验 一.使用SQL Server全文搜索配置 要使用SQL Server的全文搜索服务,需要进行如下配置. 1.开启全文搜索服务: 2.开启数据库的 ...

  3. Spring JDBCTemplate连接SQL Server之初体验

    前言 在没有任何框架的帮助下我们操作数据库都是用jdbc,耗时耗力,那么有了Spring,我们则不用重复造轮子了,先来试试Spring JDBC增删改查,其中关键就是构造JdbcTemplate类. ...

  4. .NET平台开源项目速览(15)文档数据库RavenDB-介绍与初体验

    不知不觉,“.NET平台开源项目速览“系列文章已经15篇了,每一篇都非常受欢迎,可能技术水平不高,但足够入门了.虽然工作很忙,但还是会抽空把自己知道的,已经平时遇到的好的开源项目分享出来.今天就给大家 ...

  5. Xamarin+Prism开发详解四:简单Mac OS 虚拟机安装方法与Visual Studio for Mac 初体验

    Mac OS 虚拟机安装方法 最近把自己的电脑升级了一下SSD固态硬盘,总算是有容量安装Mac 虚拟机了!经过心碎的安装探索,尝试了国内外的各种安装方法,最后在youtube上找到了一个好方法. 简单 ...

  6. Spring之初体验

                                     Spring之初体验 Spring是一个轻量级的Java Web开发框架,以IoC(Inverse of Control 控制反转)和 ...

  7. Xamarin.iOS开发初体验

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKwAAAA+CAIAAAA5/WfHAAAJrklEQVR4nO2c/VdTRxrH+wfdU84pW0

  8. 【腾讯Bugly干货分享】基于 Webpack & Vue & Vue-Router 的 SPA 初体验

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57d13a57132ff21c38110186 导语 最近这几年的前端圈子,由于 ...

  9. 【Knockout.js 学习体验之旅】(1)ko初体验

    前言 什么,你现在还在看knockout.js?这货都已经落后主流一千年了!赶紧去学Angular.React啊,再不赶紧的话,他们也要变out了哦.身旁的90后小伙伴,嘴里还塞着山东的狗不理大蒜包, ...

随机推荐

  1. Linux——DNS

    正向解析和逆向解析  正向域名解析,即DNS解析,是通过域名查询IP的解析方式.  逆向域名解析,即反向DNS解析,是通过IP地址查询域名. [root@localhost ~]# cp /var ...

  2. C# 字节转换

    1.字符串与字节数组 System.Text.Encoding.UTF-8.GetBytes() 汉字转换后3个字节,数字转换和数字位数一样 GetString() 2.Int32值类型与字节数组 B ...

  3. [WIP]php入門

    创建: 2019/06/19 安装  MAMP   变量与运算符  php标签  <?php ... ?> <?php ... ?> ● 在文件最后的 ?> 通常省略, ...

  4. P2939 [USACO09FEB]改造路Revamping Trails(分层图最短路)

    传送门 完了我好像连分层图最短路都不会了……果然还是太菜了…… 具体来说就是记录一个步数表示免费了几条边,在dijkstra的时候以步数为第一关键字,距离为第二关键字.枚举边的时候分别枚举免不免费下一 ...

  5. 根据T-Code查看用户出口的代码

    在此非常非常感谢源作者,这段代码真的非常非常有用好用! REPORT  YLBTEST. TABLES :  tstc,     "SAP Transaction Codes(SAP 事务代 ...

  6. Hadoop中解除 "Name node is in safe mode"的方法

    运行hadoop程序时,有时候会报以下错误,说明Hadoop的NameNode处在安全模式下. 原因分析: 在分布式文件系统启动的时候,开始的时候会有安全模式,当分布式文件系统处于安全模式的情况下,文 ...

  7. C# Stack堆栈的使用方法

    堆栈(Stack)代表了一个后进先出的对象集合.当您需要对各项进行后进先出的访问时,则使用堆栈.当您在列表中添加一项,称为推入元素,当您从列表中移除一项时,称为弹出元素. Stack 类的方法和属性 ...

  8. ThinkSNS+ PHP开发概述

    Plus (读音:[plʌs],全称:ThinkSNS+ [θɪŋk es en es plʌs],是 ThinkSNS 系列产品一个重要版本,其软件识别名称为 Plus 即 +) 是一个基于 Lat ...

  9. Sqlyog问题

    Sqlyog没有架构设计器的解决方法 更换注册码即可

  10. Jmeter_Beanshell_使用Java处理JSON块(转)

    [环境] ①Jmeter版本:3.2,JDK:1.8 ②前置条件:将json.jar包置于..\apache-jmeter-3.2\lib\下,并将该jar包添加到测试计划的Library中:否则会报 ...