SQLServer图数据库一些优点
上一篇簡(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ù),如下:
FROM dbo.ForumPosts ReplyPost, dbo.ForumPosts RepliedPost
?
FROM dbo.ForumPosts ReplyPost, dbo.Reply_to, dbo.ForumPosts RepliedPost
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
統(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)題。
- 上一篇: Java数字签名——RSA算法
- 下一篇: CasperJs 入门介绍