1. 程式人生 > >初識SQL Server2017 圖資料庫(一)

初識SQL Server2017 圖資料庫(一)

背景:

  圖資料庫對於表現和遍歷複雜的實體之間關係是很有效果的。而這些在傳統的關係型資料庫中尤其是對於報表而言很難實現。如果把傳統關係型資料庫比做火車的話,那麼到現在大資料時代,圖資料庫可比做高鐵。它已成為NoSQL中關注度最高,發展趨勢最明顯的資料庫。伴隨SQL Server 2017的出現,在SQL Server上面有了專門的圖資料庫,那麼以往需要其他資料庫或者效率低下地處理這些工作,現在是否可以讓我們容易的實現了那?

  接下來我會用三個篇幅介紹SQLServer 圖資料庫以及它的優缺點。

介紹:

  簡單定義:圖資料庫是NoSQL資料庫的一種型別,它應用圖形理論儲存實體之間的關係資訊。圖形資料庫是一種非關係型資料庫,它應用圖形理論儲存實體之間的關係資訊。最常見例子就是社會網路中人與人之間的關係。關係型資料庫用於儲存“關係型”資料的效果並不好,其查詢複雜、緩慢、超出預期,而圖形資料庫的獨特設計恰恰彌補了這個缺陷。

  SQL Server 2017將帶來新的功能之一就是圖資料庫。圖資料庫不像關係型資料庫在一張“圖”內將資料表現為節點,邊和屬性,而是一種抽象的資料型別,通過一組頂點節點、點和邊來表現關係和連線,就像一個纏結的漁網。使我們用簡單的方式來表現和遍歷實體間的關係。圖物件被用來表示複雜的關係。一層就是一個特定的圖,記錄如論壇帖子和回覆之間的關係,以及人與人之間的關係。多層有一個根節點(例如,論壇中的帖子和回覆),但是多個圖不一定有根節點(例如人們之間的關係)

  本文中,我們一起使用一個論壇資料例子,使用新型的圖模型。也會比較圖和關係型模型的查詢複雜度。

演示環境

建立模型

  下圖是一個關係型實體的模型,以此作為比較:

  如果想要比較,可以使用下面的指令碼建立,或者直接建立圖模型。但是,需要用SSMS建立一個新的資料庫“GraphExample”。程式碼如下:

create database GraphExample
  go
  -- Trying an entire graph model
  use GraphExample
  go
  create schema Forum
  go
  create table Forum.ForumMembers
  (MemberId int not null primary key Identity(1,1),
  MemberName varchar(100))
  go
  create table Forum.ForumPosts
  ([PostID] int not null primary key,
  PostTitle varchar(100),
  PostBody  varchar(100),
  OwnerID int,
  ReplyTo   int)
  go
  Create table Forum.Likes
  (MemberId int,
  PostId int)
  go
  create table Forum.LikeMember
  (MemberId int,
   LikedMemberId int)
   go
  INSERT Forum.ForumMembers values('Mike'),('Carl'),('Paul'),('Christy'),('Jennifer'),('Charlie')
  go
   
  INSERT INTO [Forum].[ForumPosts] 
             (
             [PostID]
             ,[PostTitle]
             ,[PostBody],OwnerID, ReplyTo
                   )
       VALUES
           (4,'Geography','Im Christy from USA',4,null),
             (1,'Intro','Hi There This is Carl',2,null)
  INSERT INTO [Forum].[ForumPosts] 
             (
             [PostID]
             ,[PostTitle]
             ,[PostBody],OwnerID, ReplyTo
                   )
       VALUES
          (8,'Intro','nice to see all here!',1,1),
          (7,'Intro','I''m Mike from Argentina',1,1),
           (6,'Re:Geography','I''m Mike from Argentina',1,4),
          (5,'Re:Geography','I''m Jennifer from Brazil',5,4),
                (3,'Re: Intro','Hey Paul This is Christy',4,2),
                   (2,'Intro','Hello I''m Paul',3,1)
  go
  INSERT Forum.Likes VALUES (1,4),
   (2,7),
   (2,8),
   (2,2),
   (4,5),
   (4,6),
   (1,2),
   (3,7),
   (3,8),
       (5,4)
  go
  Insert Forum.LikeMember VALUES (2,1),
   (2,3),
   (4,1),
   (4,5)

圖模型

  圖模型的計劃與關係型模型完全不同。表在圖模型中可能是邊或者節點。我們需要決定哪些表是邊,哪些表是節點。

  圖具有如下特徵:

    • 包含節點和邊;
    • 節點上有屬性(鍵值對);
    • 邊有名字和方向,並總是有一個開始節點和一個結束節點;
    • 邊也可以有屬性。

  下圖表現了圖模型:

 

  如圖所示,在模型中節點和邊很容易確定:邏輯模型中的所有實體就是節點,而所有關係就是邊。這裡有“Posts”和“Members”兩個實體, ‘Reply To’, ‘Like’‘Written By’三個邊。

注意

  節點和邊不過是帶有特殊欄位的表。沒有任何限制禁止我們建立常規的表之間的關係,以便將模型轉化為關係和圖模型的組合。

  例如,‘Written By’ ‘Posts’‘Members’的關係,可以轉化為一個一對多的關係。通過建立一個邊的關係表,我們可以用常規的關係表來表現所謂的圖模型中的表。也就是組合模式了。

  當我們建立一個根節點實體,這個實體接收一個叫做‘$node_id’的計算欄位。我們可以使用這個欄位作為主鍵,SQL Server 允許計算欄位作為主鍵:如果這個主鍵是一個JSON欄位,就不適合作為主鍵了。因此我們的節點必須包含兩個鍵:業務鍵,整型欄位,以及‘$node_id’ 鍵,包含整型欄位自增長的JSON鍵。

  下面為節點實體的指令碼:

Use GraphExample

  go

  CREATE TABLE [dbo].[ForumMembers](

         [MemberID] [int] IDENTITY(1,1) NOT NULL,

         [MemberName] [varchar](100) NULL

  )

  AS NODE

  GO

  

  CREATE TABLE [dbo].[ForumPosts](

         [PostID] [int] NULL,

         [PostTitle] [varchar](100) NULL,

         [PostBody] [varchar](1000) NULL

  )

  AS NODE

注意

  在建立物件後,在物件瀏覽器中檢查物件。或許此時注意到一個新的資料夾在‘Tables’資料夾裡面叫做‘Graph’。同時也注意到自增欄位的名字,儘管我們可以用簡稱來引用這些欄位,例如$node_id,但是真實的欄位名稱包含了GUID。這個簡稱欄位其實是一個假的名字,稱之為“偽列”(可以理解為別名),我們能在查詢中使用。

  如圖,插入資料到節點表:我們只需要忽略$node_id,寫出插入其他欄位的語句即可,語句如下:

INSERT ForumMembers values ('Mike'),('Carl'),('Paul'),('Christy'),('Jennifer'),('Charlie')
  INSERT INTO [dbo].[ForumPosts]

             (

             [PostID]

             ,[PostTitle]

             ,[PostBody]

                   )

       VALUES

          (8,'Intro','nice to see all here!'),

          (7,'Intro','I''m Mike from Argentina'),

           (6,'Re:Geography','I''m Mike from Argentina'),

          (5,'Re:Geography','I''m Jennifer from Brazil'),

           (4,'Geography','Im Christy from USA'),

                (3,'Re: Intro','Hey Paul This is Christy'),

             (1,'Intro','Hi There This is Carl')

                   (2,'Intro','Hello I''m Paul')

使用查詢語句可以看到ForumPosts表的結果。你會發現$node_id欄位,是一個JSON欄位包含了實體型別和一個自增整型ID,它就是自增長ID。

 

建立邊表

  這個操作很簡單,邊表有屬性,屬性就是表中的常規欄位。指令碼如下:

Create table dbo.[Written_By]

  as EDGE

  CREATE TABLE [dbo].[Likes]

  AS EDGE

  CREATE TABLE [dbo].[Reply_To]

  AS EDGE

  每個邊表有三個偽列,我們需要處理:

  • $edge_id: 邊記錄的ID
  • $from_id:在邊中記錄的節點ID
  • $to_id:在邊中記錄的其他節點ID

    注意這個定義,最為重要的一點就是:我們需要用一種合乎邏輯的方式定義  $to_id and $from_id 欄位對於每條邊意味著什麼?你可以觀察之前定義的邊表如何定義的邊,這是一種雙向的合理選擇,使得我們更容易使用和理解。

以下是我們的合理定義:

Written_By:

$from_id will be the post

$to_id will be the member

Likes:

$from_id will be who likes

$to_id will be who/what is liked

Reply_To:

$from_id will be the reply to the main post

$to_id  will be the main post

這些選擇沒有技術限制,但我們需要在插入新記錄時保留它們,永遠不要混淆關係的每一方的含義。

注意

  除了三個偽列以外,所有的表表都有額外欄位,並且全是隱藏欄位。我們可以在欄位屬性中看到隱藏的定義,並且這些隱藏欄位不會出現在查詢結果中。

插入邊記錄

    插入邊表的語句需要邊的兩端ID,$From_id and $To_id這些欄位需要用$node_id的值來填充。例如,對於一個帖子的成員,‘Written_By’包含post 的$node_id 作為$From_id 並且有member的$node_id作為$To_id欄位。

下面是插入語句:

Insert into Written_By ($to_id,$from_id) values

   (

   (select $node_id from dbo.ForumMembers where MemberId= 1 ),

   (select $node_id from dbo.ForumPosts where PostID=8 )

   ),

   (

   (select $node_id from dbo.ForumMembers where MemberId=1  ),

   (select $node_id from dbo.ForumPosts where PostID=7 )

   ),

   (

   (select $node_id from dbo.ForumMembers where MemberId= 1 ),

   (select $node_id from dbo.ForumPosts where PostID= 6)

   ),

   (

   (select $node_id from dbo.ForumMembers where MemberId=5  ),

   (select $node_id from dbo.ForumPosts where PostID=5 )

   ),

   (

   (select $node_id from dbo.ForumMembers where MemberId=4  ),

   (select $node_id from dbo.ForumPosts where PostID=4 )

   ),

   (

   (select $node_id from dbo.ForumMembers where MemberId=3  ),

   (select $node_id from dbo.ForumPosts where PostID=3 )

   ),

   (

   (select $node_id from dbo.ForumMembers where MemberId=3  ),

   (select $node_id from dbo.ForumPosts where PostID=1 )

   ),

   (

   (select $node_id from dbo.ForumMembers where MemberId=3  ),

   (select $node_id from dbo.ForumPosts where PostID=2 )

   )

注意

  這樣插入是不是感覺很麻煩?未來我們可以使用一個物件框架用以支援圖物件,目前還不支援這個功能。

  插入Reply_To指令碼如下:

	INSERT Reply_To ($to_id,$from_id) 
   VALUES
   ((SELECT $node_id FROM dbo.ForumPosts WHERE PostID = 4),
         (SELECT $node_id FROM dbo.ForumPosts WHERE PostID = 6)),
   ((SELECT $node_id FROM dbo.ForumPosts WHERE PostID = 1),
         (SELECT $node_id FROM dbo.ForumPosts WHERE PostID = 7)),
   ((SELECT $node_id FROM dbo.ForumPosts WHERE PostID = 1),
         (SELECT $node_id FROM dbo.ForumPosts WHERE PostID = 8)),
   ((SELECT $node_id FROM dbo.ForumPosts WHERE PostID = 1),
         (SELECT $node_id FROM dbo.ForumPosts WHERE PostID = 2)),
   ((SELECT $node_id FROM dbo.ForumPosts WHERE PostID = 4),
         (SELECT $node_id FROM dbo.ForumPosts WHERE PostID = 5)),
   ((SELECT $node_id FROM dbo.ForumPosts WHERE PostID = 2),
(SELECT $node_id FROM dbo.ForumPosts WHERE PostID = 3))

最後,再插入Likes:

INSERT Likes ($to_id,$from_id) 
   VALUES
   ((SELECT $node_id FROM dbo.ForumPosts WHERE PostID = 4),
         (SELECT $node_id FROM dbo.ForumMembers WHERE MemberID = 1)),
   ((SELECT $node_id FROM dbo.ForumPosts WHERE PostID = 7),
         (SELECT $node_id FROM dbo.ForumMembers WHERE MemberID = 2)),
   ((SELECT $node_id FROM dbo.ForumPosts WHERE PostID = 8),
         (SELECT $node_id FROM dbo.ForumMembers WHERE MemberID = 2)),
   ((SELECT $node_id FROM dbo.ForumPosts WHERE PostID = 2),
         (SELECT $node_id FROM dbo.ForumMembers WHERE MemberID = 2)),
   ((SELECT $node_id FROM dbo.ForumPosts WHERE PostID = 5),
         (SELECT $node_id FROM dbo.ForumMembers WHERE MemberID = 4)),
   ((SELECT $node_id FROM dbo.ForumPosts WHERE PostID = 6),
         (SELECT $node_id FROM dbo.ForumMembers WHERE MemberID = 4)),
   ((SELECT $node_id FROM dbo.ForumPosts WHERE PostID = 2),
         (SELECT $node_id FROM dbo.ForumMembers WHERE MemberID = 1)),
   ((SELECT $node_id FROM dbo.ForumPosts WHERE PostID = 7),
         (SELECT $node_id FROM dbo.ForumMembers WHERE MemberID = 3)),
   ((SELECT $node_id FROM dbo.ForumPosts WHERE PostID = 8),
         (SELECT $node_id FROM dbo.ForumMembers WHERE MemberID = 3)),
   ((SELECT $node_id FROM dbo.ForumPosts WHERE PostID = 4),
         (SELECT $node_id FROM dbo.ForumMembers WHERE MemberID = 5))

Likes 邊很好的說明了邊的功能作用。僅僅插入幾個menbers和post表的關係,但是我們可以確定在應用中成員也可能喜歡另一個成員。當然,我們也能用這個邊去關聯這個成員和其他成員的關係。在關係型模型中我們需要兩個表完成這個操作,在圖資料庫我們只需要一個邊。

下面我們在論壇的成員之間插入更多的Like:

INSERT Likes ($to_id,$from_id)

   VALUES

   ((SELECT $node_id FROM dbo.ForumMembers WHERE MemberID = 1),

         (SELECT $node_id FROM dbo.ForumMembers WHERE MemberID = 2)),

   ((SELECT $node_id FROM dbo.ForumMembers WHERE MemberID = 3),

         (SELECT $node_id FROM dbo.ForumMembers WHERE MemberID = 2)),

   ((SELECT $node_id FROM dbo.ForumMembers WHERE MemberID = 1),

         (SELECT $node_id FROM dbo.ForumMembers WHERE MemberID = 4)),

   ((SELECT $node_id FROM dbo.ForumMembers WHERE MemberID = 5),

         (SELECT $node_id FROM dbo.ForumMembers WHERE MemberID = 4))

小結

  本篇介紹了圖資料庫的一些簡單定義和理解,概述了SQLServer2017中如何建立圖資料庫的基本步驟和語句。這只是一個初步版本必然有很多缺點,當然也有一些優點,下一篇我將先介紹優點再說一下有哪些不足。

參考文獻:https://www.red-gate.com/simple-talk/sql/t-sql-programming/sql-graph-objects-sql-server-2017

相關推薦

初識SQL Server2017 資料庫

背景:   圖資料庫對於表現和遍歷複雜的實體之間關係是很有效果的。而這些在傳統的關係型資料庫中尤其是對於報表而言很難實現。如果把傳統關係型資料庫比做火車的話,那麼到現在大資料時代,圖資料庫可比做高鐵。它已成為NoSQL中關注度最高,發展趨勢最明顯的資料庫。伴隨SQL Server 2017的出現,在SQL S

SQL Server 到 MySQL :異構資料庫遷移

背景 滬江成立於 2001 年,作為較早期的教育學習網站, 當時技術選型範圍並不大: Java 的版本是 1.2,C# 尚未誕生,MySQL 還沒有被 Sun 收購, 版本號是 3.23。 工程師們選擇了當時最合適的微軟體系,並在日後的歲月裡, 逐步從 ASP 過度到 .net,資料庫也跟隨 SQL Ser

崔華基於oracle的SQL優化讀書筆記如何得到真實的執行計劃

hash mes getting binary oracl only 中文 fun roc ---恢復內容開始--- 得到目標SQL的執行計劃,大致有以下四種方式: 1.explain plan 命令 2.DBMS_XPLAN包 3.SQLPLUS中的autotrace開關

PL/SQL批處理語句BULK COLLECT

數據 使用 for循環 差異 code 基於 name 從表 允許 我們知道PL/SQL程序中運行SQL語句是存在開銷的,因為SQL語句是要提交給SQL引擎處理,這種在PL/SQL引擎和SQL引擎之間的控制轉移叫做上下文卻換,每次卻換時,都有額外的開銷。然而,FORALL和

初識ExtJS 6----自學筆記

6.2 漂亮 VM 部分 判斷 .cn onf 版本 template 一、使用環境 這一點寫在前面,是為了方便大家在找資料的時候可以直接定位環境版本。 ExtJS版本 6.2 中文官方網站提供版本,網站地址http://extjs.org

前端PS切技巧

發現 右下角 放大 比較 clas ng- ring 練習 span UI給我們設計圖的時候都會有一份設計原稿psd文件,有的公司可能UI會把需要的圖標給切好,更多時候是需要我們自己來切的。而且,有的時候可能需要的東西UI沒有切出來,你就要去是去找UI切好了再發給我們,這個

SQL Server進階T-SQL查詢和編程的背景

.com src 編程 server 分享 bubuko 進階 分享圖片 img SQL Server進階(一)T-SQL查詢和編程的背景

PL/SQL程式設計基礎知識

--PL/SQL變數的宣告和賦值 declare v_ename varchar2(30);--定義變數 begin v_ename:='&請輸入名字';--接受鍵盤輸入 dbms_output.put_line(v_ename); end; --put_line :列印換行

Redtiger SQL註入練習

username shu The 查詢 info format print 多次 ali 感覺會的東西太少了,以後要多練習,多寫博客。要堅持學習,一定不能放棄,為夢想奮鬥。 redtiger 這個平臺早就開始做了,但是才做到第4關。。。。 第一關: 打開題,

網頁註冊登入資料庫

登入頁面 <%@ page language="java" import="java.util.*" contentType="text/html;charset=utf-8"%> <html> <head> <title>使用者登入<

淺談資料庫

** 1、MySQL概述 a、什麼是資料庫 儲存資料的倉庫 b、哪些公司在用資料庫 金融機構、遊戲網站、購物網站、論壇網站 ... ... c、資料庫服務軟體 ***1、軟體分類*** MySQL、Oracle、SQL_Server、MongoDB、DB2、M

MySQL資料庫__2018.10.29

1.模糊查詢:SELECT *FROM info WHERE 密碼1 LIKE'%89%'; 資料庫通過SQL語言來管理。 DDL:資料定義語言 DML:資料操作語言 DQL:資料查詢語言 DCL:資料控制語言 整合開發環境:MAMP、MapServer。 通過寫一些SQ

python3入門教程操作資料庫

概述   最近在準備寫一個爬蟲的練手專案,基本想法是把某新聞網站的內容分類爬取下來,儲存至資料庫,再通過介面對外輸出(提供後臺查詢介面)。那麼問題就來了,python到底是怎麼去操作資料庫的呢?我們今天就來研究下。   準備 我這邊資料庫使用的是mysql5.7,python去操作mysql

1 小時 SQL 極速入門

前幾天,我在論壇溜達。看到一個人發帖說 做了6年的企業級開發,總是被網際網路行業的人認為沒技術含量,不就是CRUD麼 先解釋下 CRUD 是什麼。CRUD 就是我們常說的增刪改查(Create,Retrieve,Update,Delete) 其實,對這個問題,我也思考過。我們所有的業務流程,最終

MySQL資料庫編譯安裝、安裝後優化操作及超戶忘記資料庫密碼的解決方法

MySQL的下載地址:http://www.dev.mysql.com/downloads 準備工作:解除安裝rpm方式安裝的mysql-server、mysql       rpm -qa | grep mysql 若存在,用rpm -e mysql-server mysql --nodeps命令解除

淘淘商城系列—— 首頁輪播展示

首頁輪播圖展示 taotao-portal-web工程中,動態展示內容資訊。 前端團隊:負責JS,html等開發。 後端團隊:負責後臺的開發並提供資料給前端。 1、功能分析 只需要動態生成一個json資料,輪播圖就可以動態展示: taotao-portal

Linux —mysql資料庫

本章內容 關係型資料庫基礎 安裝MySQL 管理資料庫和表 使用者和許可權管理 函式和儲存過程 MySQL架構 儲存引擎 伺服器選項,系統和狀態變數 優化查詢和索引管理 鎖和事務管理 日誌管理 ###必須掌握 備份還原 ###必須掌握

毛毛Python進階之路6——MySQL 資料庫

毛毛Python進階之路6——MySQL 資料庫(一) DBMS 系統:資料庫管理系統。 一、安裝和下載: MySQL有兩種安裝方式,一種可執行檔案(點點點就可以),另一種是壓縮包式,需要有一定的基礎,比如新增環境變數,新增程序等等。 1、新增環境變數:計算機屬性-高階系統

SQL server2008基本操作

SQL server2008基本操作 目錄  1.註冊伺服器 (1)註冊一個本地伺服器S1,測試註冊是否成功,如果成功則儲存該伺服器註冊。步驟: 第1步:開啟SQL Server Management Studio視窗→“檢視” → “

Android資料持久化—SQLite資料庫-建立資料庫

       在編寫軟體的過程中,我們通常會在移動裝置的本地儲存一些資料,這些資料如何儲存,就是使用到一個android 端的輕量級資料庫SQLite,在資料儲存大家都應該使用過SharedPreferences,這個東西只適合儲存一些簡單的資料,但是到了