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. servlet与filter的加载顺序详解

     项目:3个filter,3个servlet,匹配的url路径/hello. 情况1:servlet没加<load-on-startup></load-on-startup>情 ...

  2. 4.Windows应急响应:勒索病毒

    0x00 前言 勒索病毒,是一种新型电脑病毒,主要以邮件.程序木马.网页挂马的形式进行传播.该病毒性质恶劣. 危害极大,一旦感染将给用户带来无法估量的损失.这种病毒利用各种加密算法对文件进行加密,被感 ...

  3. idea使用的知识

    1. 如何设置,使IntelliJ IDEA智能提示忽略大小写.    很好用,在settings->Editor->General-->Code Completion里设置.2. ...

  4. 【service调用dao层传参的三种方式】

    第一种方案:默认数组角标: service Public User selectUser(String name,String area); mapper: <select id="s ...

  5. 定时处理组件---Quartz.net

    1.认识任务调度 所谓任务调度,就是以将业务区块任务化(即抽象成每一个独立的任务,执行每个任务便完成某种业务的需求).比如,我们有一个订单系统,现在有这样的一个需求,就是需要在某一时间点去扫描数据库, ...

  6. Beta博客总结

    描述项目预期计划和现实进展 冲刺 时间 预期任务以及预估时间 现实完成情况以及实际用时 冲刺1 12.4 修改等级答题界面:30,修改获取用户信息接口:30 修改等级答题界面:60,修改获取用户信息接 ...

  7. Android代码笔记

    1. 如何监听Android的短信收发,自动填充验证码? getContentResolver().registerContentObserver(Uri.parse(SMS_URI_ALL), tr ...

  8. Node.js 内置模块crypto使用事件方法(onreadable)加密的一些问题

    javaScript代码如下: 'use strict'; const crypto = require('crypto'); //实例化一个AES加密对象 const aesEncrept = cr ...

  9. FJOI2019全记录(福建省选)

    Day 0 最后一个早上,早读完后就到机房里,复习了左偏树和计算几何,然后真的不知道还要做什么了(FFT和一些数论的结论昨天复习过了 也许还要去学一点新东西(?),像Krusk重构树什么的.(一直没有 ...

  10. Exadata中Infiniband交换机升级

    Infiniband交换机的软件补丁包,随着软件版本的不同,其发布方式也有所变化,从如下图表可以看出,1.3.3-2这个版本是一个分水岭,这个版本及以前的版本,补丁包是单独下载的,而之后的版本,inf ...