初識SQL Server2017 圖資料庫(一)

来源:http://www.cnblogs.com/wenBlog/archive/2017/10/18/7685554.html
-Advertisement-
Play Games

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


背景:

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

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

介紹:

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

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

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

演示環境

  SQL Server 2017 CTP 2.1下載地址: https://www.microsoft.com/en-us/sql-server/sql-server-2017

  使用SSMS 17.0,下載地址: https://docs.microsoft.com/en-us/sql/ssms/download-sql-server-management-studio-ssms

創建模型

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

 

  如果想要比較,可以使用下麵的腳本創建,或者直接創建圖模型。但是,需要用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

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 用SpannableString打造絢麗多彩的文本顯示效果 引語 TeXtView大家應該都不陌生,文本展示控制項嘛! 就用TextView顯示普普通通的文本,OK,很簡單,Android入門的都會,沒入門的在門縫外看兩眼也都會,哈哈,開玩笑。那要是設計在開發需求中要求類似微信聊天表情一樣在TextV ...
  • BHInfiniteScrollView 圖片輪播庫,支持圖片左右滾動,上下滾動 https://github.com/qylibohao/BHInfiniteScrollView TZImagePickerController 支持多選、選原圖和視頻的圖片選擇器 https://github.co ...
  • 本例中udf來自《hive編程指南》其中13章自定義函數中一個例子。 按照步驟,第一步,建立一個項目,創建 GenericUDFNvl 類。 創建完成之後,在項目中點郵件->Export->JAR file,再下一步中選中剛剛創建的這個文件,將文件導出為.jar文件。 接下來,進入hive的 CLI ...
  • 0.目錄 1. "前言" 2. "準備工作" 3. "簡單測試語句" 4. "提交與回滾" 5. "封裝成類的寫法" 1.前言 前面學完了SQL Server的基本語法,接下來學習如何在程式中使用sql,畢竟不能在程式中使用的話,實用性就不那麼大了。 2.最基本的SQL查詢語句 python是使用p ...
  • AutoAudit介紹 AutoAudit這個是Paul Nielsen寫的一個開源的審計跟蹤的腳本項目,項目位於https://autoaudit.codeplex.com/上,Paul Nielsen的一篇博客CodeGen to Create Fixed Audit Trail Trigger... ...
  • 最近需要將Mysql的資料庫導出一份Word的文檔出來,本文記錄調研後幾個可用的工具和方法 ...
  • 操作系統 :CentOS7.3.1611_x64 PostgreSQL版本 :9.6 問題描述 PostgreSQL執行Insert語句時,自動填入時間的功能可以在創建表時實現,但更新表時時間戳不會自動自動更新。 在mysql中可以在創建表時定義自動更新欄位,比如 : 那PostgreSQL中怎麼操 ...
  • 圖示池化層(前向傳播) 池化層其實和捲積層有點相似,有個類似捲積核的視窗按照固定的步長在移動,每個視窗做一定的操作,按照這個操作的類型可以分為兩種池化層: MAC (max pooling)在視窗中取最大值當做結果 AVG (average pooling)在視窗中取平均值當做結果 池化層的反向傳播 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...