日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

SQLServer图数据库一些优点

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

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

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

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

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

    FROM dbo.ForumPosts ReplyPost, dbo.ForumPosts RepliedPost

    ?

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

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

    ?

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

    ?

  • 這個(gè)語(yǔ)法很有意思:“-”破折號(hào)表示邊的$From_id字段表示關(guān)系,然后“->”破折號(hào)和大于號(hào)用邊的$To_id字段表示關(guān)系。
  • 因?yàn)橹滥莻€(gè)別名有reply,那個(gè)別名有replied post,我們可以構(gòu)建一個(gè)查詢字段列表:
  • 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

    ?

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

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

    ?

  • 還要添加MATCH語(yǔ)句的內(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)系型模型中的對(duì)應(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ù)對(duì)象的名字。像上面一樣增加‘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

    ?

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

    ?

  • 注意這個(gè)符號(hào)“<-”與之前的相反方向,但是意義是相同的:一個(gè)在邊表的$to_id與節(jié)點(diǎn)表的關(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)系型查詢的對(duì)應(yīng)語(yǔ)句:
  • 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

    ?

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

    ?

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

    根貼(主貼)的列表

    我們通過(guò)下面不使用MATCH的語(yǔ)句得到所有的根貼:

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

    ?

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

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

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

    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

    ?

    ?

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

    使用CTE遞歸語(yǔ)法,我們可以用一種樹結(jié)構(gòu)檢索一個(gè)帖子的所有回復(fù)。如果使用常規(guī)的語(yǔ)法不能在檢索帖子1的時(shí)候檢索貼子3,因?yàn)?是對(duì)2的回復(fù),而2是對(duì)1的回復(fù)。使用CTE.當(dāng)查詢帖子1的所有回復(fù)時(shí)能檢索貼子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

    ?

    我們也可以反過(guò)來(lái)做,在樹狀結(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

    檢索一個(gè)用戶所有帖子

    查詢一個(gè)用所有的信息,與帖子不同,這不需要樹,要簡(jiǎn)單不少:

    -- 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'

    ?

    或許你注意到上面兩個(gè)查詢的不同,就是在展示字段上是否使用DISTINCT。這個(gè)去重是因?yàn)镻eter回復(fù)同一個(gè)帖子可以超過(guò)一次。

    在模型中檢索Likes(點(diǎn)贊)

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

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

    ?

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

    --每個(gè)帖子總的likesselect Post.PostId,Post.PostTitle,count(*) totalLikesfrom dbo.ForumPosts Post,Likes,dbo.ForumMembers Memberswhere Match(Members-(Likes)->Post)group by PostId,PostTitle--每個(gè)成員總的點(diǎn)贊數(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

    ?

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

    我們也可以創(chuàng)建一些更有趣的查詢,例如,查找這些點(diǎn)贊并回復(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)

    ?

    注意,對(duì)于‘Member’節(jié)點(diǎn)使用了兩次在同一個(gè)MATCH表達(dá)式中。這形成了一種過(guò)濾:點(diǎn)贊并且有回復(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

    ?

    看起來(lái)這種寫法更難理解和讀懂。

    回帖給多個(gè)帖子的成員

    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

    ?

    回帖個(gè)一個(gè)帖子多次的成員:

    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

    ?

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

    總結(jié)

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

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

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

    總結(jié)

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

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