日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

SQLServer图数据库一些优点

發(fā)布時間:2025/5/22 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SQLServer图数据库一些优点 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
SQLServer圖數(shù)據(jù)庫一些優(yōu)點 原文:SQLServer圖數(shù)據(jù)庫一些優(yōu)點

    上一篇簡要介紹了圖數(shù)據(jù)庫的一些基本內(nèi)容(初識SQL Server2017 圖數(shù)據(jù)庫(一)),本篇通過對比關(guān)系型一些語法來體現(xiàn)圖數(shù)據(jù)庫模式的一些優(yōu)點,比如查詢方便,語句易理解等。

在圖數(shù)據(jù)庫模型上構(gòu)建查詢的優(yōu)勢:

T-SQL 帶給圖表查詢一些新的語法。在SELECT語句中我們有一些特殊的語句來關(guān)聯(lián)點和邊。讓我們來演練一些,構(gòu)建查詢語句檢索發(fā)帖和回復(fù),如下:

  • 我們檢索每個記錄的兩個部分,發(fā)帖和回復(fù),因此我們需要在FROM子句中引用兩次ForumPosts’表,這個地方可以采用一些有意義的別名:
  •     

    FROM dbo.ForumPosts ReplyPost, dbo.ForumPosts RepliedPost

    ?

  • 盡管我們能選擇任何別名,但是在處理圖對象時最好選擇有意義的名字。
  • 我們需要“posts”之間的關(guān)系,而這個關(guān)系就是表Reply_to’。語法如下:
  •     

    FROM dbo.ForumPosts ReplyPost, dbo.Reply_to, dbo.ForumPosts RepliedPost

    ?

  • 在WHERE 子句中,我們需要關(guān)聯(lián)所有的表,用下面這種MATCH語句來實現(xiàn)關(guān)聯(lián):
  • FROM dbo.ForumPosts ReplyPost, dbo.Reply_to, dbo.ForumPosts RepliedPostWHERE MATCH(ReplyPost-(Reply_to)->RepliedPost)

    ?

  • 這個語法很有意思:“-”破折號表示邊的$From_id字段表示關(guān)系,然后“->”破折號和大于號用邊的$To_id字段表示關(guān)系。
  • 因為知道那個別名有reply,那個別名有replied post,我們可以構(gòu)建一個查詢字段列表:
  • FROM dbo.ForumPosts ReplyPost, dbo.Reply_to, dbo.ForumPosts RepliedPostWHERE MATCH(ReplyPost-(Reply_to)->RepliedPost)

    ?

  • 在關(guān)系型模型中相同功能的查詢?nèi)缦?
  • select RepliedPost.PostId,RepliedPost.PostTitle,ReplyPost.PostId as ReplyId, ReplyPost.PostTitle as ReplyTitlefrom Forum.ForumPosts ReplyPost, Forum.ForumPosts RepliedPostwhere ReplyPost.PostId=RepliedPost.ReplyTo

    ?

  • 這些查詢很相似,當然MATCH的語法更容易理解。
  • 執(zhí)行完上面語句查詢結(jié)果如下:
  • ?

  • 我們加上寫這個回復(fù)貼人的名字。需要在FROM子句中添加‘ForumMembers’節(jié)點和‘Written_By’這個邊。語句如下:
  • FROM dbo.ForumPosts ReplyPost, dbo.Reply_to, dbo.ForumPosts RepliedPost, dbo.ForumMembers RepliedMember, Written_By RepliedWritten_By

    ?

  • 還要添加MATCH語句的內(nèi)部關(guān)系:
  • WHERE MATCH(ReplyPost-(Reply_to)->RepliedPost-(RepliedWritten_by)->RepliedMember)

    ?

  • 這就可以在SELECT列表中添加回帖人的名字,最終的查詢?nèi)缦?#xff1a;
  • -- Posts 、members 和repliesSELECT RepliedPost.PostId,RepliedPost.PostTitle,RepliedMember.MemberName,ReplyPost.PostId as ReplyId, ReplyPost.PostTitle as ReplyTitleFROM dbo.ForumPosts ReplyPost, dbo.Reply_to, dbo.ForumPosts RepliedPost,dbo.ForumMembers RepliedMember, Written_By RepliedWritten_ByWHERE MATCH(ReplyPost-(Reply_to)->RepliedPost-(RepliedWritten_by)->RepliedMember)

    ?

  • 在關(guān)系型模型中的對應(yīng)查詢?nèi)缦?#xff1a;
  • SELECT RepliedPost.PostId,RepliedPost.PostTitle,ReplyPost.PostId as ReplyId, ReplyPost.PostTitle as ReplyTitle,RepliedMember.MemberNameFROM Forum.ForumPosts ReplyPost, Forum.ForumPosts RepliedPost,Forum.ForumMembers RepliedMemberWHERE ReplyPost.PostId=RepliedPost.ReplyToand RepliedPost.OwnerId=RepliedMember.MemberId

    ?

  • 結(jié)果如下所示:
  • ?

  • 還缺少回復(fù)對象的名字。像上面一樣增加‘ForumMembers’ 和 ?‘Written_By’在FROM子句中:
  • From dbo.ForumPosts ReplyPost, dbo.Reply_to, dbo.ForumPosts RepliedPost,dbo.ForumMembers RepliedMember, Written_By RepliedWritten_By,dbo.ForumMembers ReplyMember, Written_By ReplyWritten_By

    ?

  • 接下來,修改MATCH子句,‘ReplyMember’需要關(guān)聯(lián)‘ReplyPost’,但是如何去處理這個關(guān)系而不影響其他關(guān)系?需要用不同的方式來實現(xiàn):
  • WHERE MATCH(ReplyMember<-(ReplyWritten_By)-ReplyPost-(Reply_to)->RepliedPost-(RepliedWritten_by)->RepliedMember)

    ?

  • 注意這個符號“<-”與之前的相反方向,但是意義是相同的:一個在邊表的$to_id與節(jié)點表的關(guān)系。
  • 最終,還需增加寫著回復(fù)的成員姓名,代碼如下:
  • -- Posts and members and their replies and membersSELECT RepliedPost.PostId, RepliedPost.PostTitle,RepliedMember.MemberName,ReplyPost.PostId as ReplyId, ReplyPost.PostTitle as ReplyTitle,ReplyMember.MemberName [ReplyMemberName]FROM dbo.ForumPosts ReplyPost, dbo.Reply_to, dbo.ForumPosts RepliedPost,dbo.ForumMembers RepliedMember, Written_By RepliedWritten_By,dbo.ForumMembers ReplyMember, Written_By ReplyWritten_ByWHERE MATCH(ReplyMember<-(ReplyWritten_By)-ReplyPost-(Reply_to)->RepliedPost-(RepliedWritten_by)->RepliedMember)

    ?

  • 結(jié)果集如下:
  • ?

  • 在關(guān)系型查詢的對應(yīng)語句:
  • SELECT RepliedPost.PostId,RepliedPost.PostTitle,RepliedMember.MemberName, ReplyPost.PostId as ReplyId,ReplyPost.PostTitle as ReplyTitle, ReplyMember.MemberNameFROM Forum.ForumPosts ReplyPost, Forum.ForumPosts RepliedPost,Forum.ForumMembers RepliedMember, Forum.ForumMembers ReplyMemberWHERE ReplyPost.PostId=RepliedPost.ReplyToand RepliedPost.OwnerId=RepliedMember.MemberIdand ReplyPost.OwnerId=ReplyMember.MemberId

    ?

  • 在這個時候,可能在關(guān)系型模式里面隨著關(guān)系的增多讀取就會越困難,而在圖數(shù)據(jù)模式中MATCH子句相對就容易很多。讓我們看一下在圖數(shù)據(jù)模式中一些有趣又有用的地方。
  • 統(tǒng)計每篇帖子的回復(fù)數(shù)

    SELECT distinct RepliedPost.PostID,RepliedPost.PostTitle,RepliedPost.PostBody,count(ReplyPost.PostID) over(partition by RepliedPost.PostID)as TotalRepliesFROM dbo.ForumPosts ReplyPost, Reply_To, dbo.ForumPosts RepliedPostWHERE MATCH(ReplyPost-(Reply_To)->RepliedPost)

    ?

    在這個語句中我們統(tǒng)計了每一篇回復(fù)的數(shù)量,但是僅僅在一個層面中,并不是在整個回復(fù)的樹結(jié)構(gòu)里面。

    根貼(主貼)的列表

    我們通過下面不使用MATCH的語句得到所有的根貼:

    SELECT Post1.PostId,Post1.PostTitleFROM dbo.ForumPosts Post1WHERE $node_id not in (select $from_id from dbo.Reply_To

    ?

    MATCH語法只是允許我們關(guān)聯(lián)三個或者更多的實體(比如兩個節(jié)點和一個關(guān)系)。當我們只想關(guān)聯(lián)其中兩個的時候,只需要一個常規(guī)的連接或者子查詢。如上面的語句一樣。

    在結(jié)果中添加‘Level’字段

    添加一個‘Level’字段,顯示樹結(jié)構(gòu)。在T-SQL中有一個簡單的語法,叫做CTE實現(xiàn)遞歸。但是有一個問題,不能使用MATCH語法在一個派生表上,此時可以使用CTE。如果有必要,可以在CTE中使用MATCH,但是反之就不行了,有這樣的限制。下面展示一下使用常規(guī)的關(guān)系僅僅使用CTE來迭代,代碼如下:

    with root as( select $node_id as node_id,RootPosts.PostId,RootPosts.PostTitle,1 as Level, 0 as ReplyTofrom dbo.ForumPosts RootPostswhere $node_id not in (select $from_id from dbo.reply_to)union allselect $node_id,ReplyPost.PostId, ReplyPost.PostTitle,Level+1 as [Level], root.PostId as ReplyTofrom dbo.ForumPosts ReplyPost, reply_to, rootwhere ReplyPost.$node_id=reply_to.$from_idand root.node_id=reply_to.$to_id)select PostId,PostTitle, Level, ReplyTofrom root

    ?

    ?

    檢索一個帖子中的所有回復(fù)

    使用CTE遞歸語法,我們可以用一種樹結(jié)構(gòu)檢索一個帖子的所有回復(fù)。如果使用常規(guī)的語法不能在檢索帖子1的時候檢索貼子3,因為3是對2的回復(fù),而2是對1的回復(fù)。使用CTE.當查詢帖子1的所有回復(fù)時能檢索貼子3。代碼如下:

    with root as( select $node_id as node_id,RootPosts.PostId,RootPosts.PostTitle,1 as Level, 0 as ReplyTofrom dbo.ForumPosts RootPostswhere PostId=1 union allselect $node_id,ReplyPost.PostId, ReplyPost.PostTitle,Level+1 as [Level],root.PostId as ReplyTofrom dbo.ForumPosts ReplyPost, reply_to, rootwhere ReplyPost.$node_id=reply_to.$from_idand root.node_id=reply_to.$to_id)select PostId,PostTitle, Level, ReplyTofrom root

    ?

    我們也可以反過來做,在樹狀結(jié)構(gòu)中按順序檢索所有父貼。由于CTE不支持OUTER join,所以要在外部添加,代碼如下:

    with root as( select LeafPost.$node_id as node_id,LeafPost.PostId,LeafPost.PostTitlefrom dbo.ForumPosts LeafPostwhere LeafPost.PostId=3 -- Single postunion allselect RepliedPost.$node_id as node_id,RepliedPost.PostId,RepliedPost.PostTitlefrom dbo.ForumPosts RepliedPost, Reply_to, rootwhere root.node_id=Reply_to.$from_idand Reply_to.$to_id=RepliedPost.$node_id)select root.PostId,root.PostTitle,RepliedPost.PostId ParentPostIdfrom rootleft join reply_toon root.node_id=reply_to.$from_idleft join dbo.ForumPosts RepliedPoston reply_to.$to_id=RepliedPost.$node_id

    檢索一個用戶所有帖子

    查詢一個用所有的信息,與帖子不同,這不需要樹,要簡單不少:

    -- Peter回復(fù)的所有帖子SELECT distinct RepliedPost.PostID,RepliedPost.PostTitle,RepliedPost.PostBodyFROM dbo.ForumPosts ReplyPost, Reply_To, dbo.ForumPosts RepliedPost,dbo.ForumMembers Members,Written_ByWHERE MATCH(Members<-(Written_By)-ReplyPost-(Reply_To)->RepliedPost)and Members.MemberName='Peter'-- Peter發(fā)的所有帖子SELECT ReplyPost.PostID,ReplyPost.PostTitle,ReplyPost.PostBody,RepliedPost.PostId ReplyToFROM dbo.ForumPosts ReplyPost, Reply_To, dbo.ForumPosts RepliedPost,dbo.ForumMembers Members,Written_ByWHERE MATCH(Members<-(Written_By)-ReplyPost-(Reply_To)->RepliedPost)and Members.MemberName='Peter'

    ?

    或許你注意到上面兩個查詢的不同,就是在展示字段上是否使用DISTINCT。這個去重是因為Peter回復(fù)同一個帖子可以超過一次。

    在模型中檢索Likes(點贊)

    這個查詢是有意思的:‘Likes’邊是成員和發(fā)帖表的關(guān)系。每一個關(guān)系都是唯一的,并不受其他關(guān)系影響。代碼如下:

    --點贊的帖子或者被別人點贊的帖子。SELECT Post.PostID,Post.PostTitle,Member.MemberNameFROM dbo.ForumPosts Post, Likes,dbo.ForumMembers MemberWHERE MATCH(Member-(Likes)->Post)-- 點贊的人或者被人點贊SELECT Member.MemberId,Member.MemberName LikeMember,LikedMember.MemberName LikedMemberNameFROM dbo.ForumMembers Member, Likes, dbo.ForumMembers LikedMemberWHERE MATCH(Member-(Likes)->LikedMember)

    ?

    還可以很容易地聚合信息,以獲得每個帖子或每個成員的總的Likes。

    --每個帖子總的likesselect Post.PostId,Post.PostTitle,count(*) totalLikesfrom dbo.ForumPosts Post,Likes,dbo.ForumMembers Memberswhere Match(Members-(Likes)->Post)group by PostId,PostTitle--每個成員總的點贊數(shù)select LikedMembers.MemberId,LikedMembers.MemberName,count(*) totalLikesfrom dbo.ForumMembers Members,Likes,dbo.ForumMembers LikedMemberswhere Match(Members-(Likes)->LikedMembers)group by LikedMembers.MemberId,LikedMembers.MemberName

    ?

    用戶點贊并且回復(fù)帖子

    我們也可以創(chuàng)建一些更有趣的查詢,例如,查找這些點贊并回復(fù)的人,如下:

    SELECT Member.MemberName,Member.Memberid,LikedPost.PostId,LikedPost.PostTitle,ReplyPost.PostTitle ReplyTitleFROM dbo.ForumPosts LikedPost, Reply_To, dbo.ForumPosts ReplyPost,Likes, dbo.ForumMembers Member, Written_ByWHERE MATCH(Member-(Likes)->LikedPost<-(Reply_To)-ReplyPost-(Written_By)->Member)

    ?

    注意,對于‘Member’節(jié)點使用了兩次在同一個MATCH表達式中。這形成了一種過濾:點贊并且有回復(fù)的成員,需要在‘LikedPost’和‘ReplyPost’中都有記錄才可以。

    那么在關(guān)系型模式中代碼如下:

    select Likes.MemberId,Members.MemberNamefrom Forum.Likes Likes, Forum.ForumPosts Posts,Forum.ForumMembers Memberswhere Likes.MemberId=Posts.OwnerIdand Posts.ReplyTo=Likes.PostIdand Members.MemberId=Likes.MemberId

    ?

    看起來這種寫法更難理解和讀懂。

    回帖給多個帖子的成員

    SELECT Members.MemberId, Members.MemberName,Count(distinct RepliedPost.PostId) as TotalFROM dbo.ForumPosts ReplyPost, Reply_To, dbo.ForumPosts RepliedPost,Written_By,dbo.ForumMembers MembersWHERE MATCH(Members<-(Written_By)-ReplyPost-(Reply_To)->RepliedPost)GROUP BY MemberId, Members.MemberNameHaving Count(RepliedPost.PostId) >1

    ?

    回帖個一個帖子多次的成員:

    SELECT Members.MemberId, Members.MemberName,RepliedPost.PostId RepliedId,count(*) as TotalRepliesFROM dbo.ForumPosts ReplyPost, Reply_To, dbo.ForumPosts RepliedPost,Written_By,dbo.ForumMembers MembersWHERE MATCH(Members<-(Written_By)-ReplyPost-(Reply_To)->RepliedPost)GROUP BY MemberId,MemberName,RepliedPost.PostIdHaving count(*) >1

    ?

    上述兩種語句中唯一的不同就是展示結(jié)果的聚合。

    總結(jié)

      通過上述構(gòu)建在圖數(shù)據(jù)模式下的查詢和關(guān)聯(lián),對比了常規(guī)語句以及在關(guān)系模式下的相同查詢,不難發(fā)現(xiàn)無論是在易讀性,邏輯理解上還是在性能上都有很大提高。當然這只是第一個版本,所以難免有很多問題, 下一篇我講介紹這個版本存在的一部分問題。

    posted on 2018-01-25 08:41 NET未來之路 閱讀(...) 評論(...) 編輯 收藏

    轉(zhuǎn)載于:https://www.cnblogs.com/lonelyxmas/p/8349445.html

    總結(jié)

    以上是生活随笔為你收集整理的SQLServer图数据库一些优点的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。