- 1、本文档共12页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
逻辑数据库设计 - 单纯的树(递归关系数据)相信有过开发经验的朋友都曾碰到过这样一个需求。假设你正在为一个新闻网站开发一个评论功能,读者可以评论原文甚至相互回复。
这个需求并不简单,相互回复会导致无限多的分支,无限多的祖先-后代关系。这是一种典型的递归关系数据。
对于这个问题,以下给出几个解决方案,各位客观可斟酌后选择。
一、邻接表:依赖父节点
邻接表的方案如下(仅仅说明问题):
CREATE TABLE Comments(
CommentI PK,
ParentId int, --记录父节点
ArticleI,
CommentBody nvarchar(500),
FOREIGN KEY (ParentId) REFERENCES Comments(CommentId) --自连接,主键外键都在自己表内
FOREIGN KEY (ArticleId) REFERENCES Articles(ArticleId)
)
由于偷懒,所以采用了书本中的图了,Bugs就是Articles:
这种设计方式就叫做邻接表。这可能是存储分层结构数据中最普通的方案了。
下面给出一些数据来显示一下评论表中的分层结构数据。示例表:
图片说明存储结构:
邻接表的优缺分析
对于以上邻接表,很多程序员已经将其当成默认的解决方案了,但即便是这样,但它在从前还是有存在的问题的。
分析1:查询一个节点的所有后代(求子树)怎么查呢?
我们先看看以前查询两层的数据的SQL语句:
SELECT c1.*,c2.*
FROM Comments c1 LEFT OUTER JOIN Comments2 c2
ON c2.ParentId = c1.CommentId
显然,每需要查多一层,就需要联结多一次表。SQL查询的联结次数是有限的,因此不能无限深的获取所有的后代。而且,这种这样联结,执行Count()这样的聚合函数也相当困难。
说了是以前了,现在什么时代了,在SQLServer 2005之后,一个公用表表达式就搞定了,顺带解决的还有聚合函数的问题(聚合函数如Count()也能够简单实用),例如查询评论4的所有子节点:
WITH COMMENT_CTE(CommentId,ParentId,CommentBody,tLevel)
AS
(
--基本语句
SELECT CommentId,ParentId,CommentBody,0 AS tLevel FROM Comment
WHERE ParentId = 4
UNION ALL --递归语句
SELECT c.CommentId,c.ParentId,c.CommentBody,ce.tLevel + 1 FROM Comment AS c
INNER JOIN COMMENT_CTE AS ce --递归查询
ON c.ParentId = ce.CommentId
)
SELECT * FROM COMMENT_CTE
显示结果如下:
那么查询祖先节点树又如何查呢?例如查节点6的所有祖先节点:
WITH COMMENT_CTE(CommentId,ParentId,CommentBody,tLevel)
AS
(
--基本语句
SELECT CommentId,ParentId,CommentBody,0 AS tLevel FROM Comment
WHERE CommentId = 6
UNION ALL
SELECT c.CommentId,c.ParentId,c.CommentBody,ce.tLevel - 1 FROM Comment AS c
INNER JOIN COMMENT_CTE AS ce --递归查询
ON ce.ParentId = c.CommentId
where ce.CommentId ce.ParentId
)
SELECT * FROM COMMENT_CTE ORDER BY CommentId ASC
结果如下:
再者,由于公用表表达式能够控制递归的深度,因此,你可以简单获得任意层级的子树。
OPTION(MAXRECURSION 2)
看来哥是为邻接表平反来的。
?分析2:当然,邻接表也有其优点的,例如要添加一条记录是非常方便的。
INSERT INTO Comment(ArticleId,ParentI
您可能关注的文档
最近下载
- 第20课 五四运动与中国共产党的诞生必修中外历史纲要上 (2).pptx VIP
- 久谦-中信产业基金第三方物流及快递投资目标筛选项目 v3.6-20120118.pptx VIP
- 《景观生态学》全套教学课件.ppt
- 幼儿园公开招聘教职员工简章.pdf
- 2023年财务分析题库完整版.doc
- CJJ∕T 135-2009 (2023年版) 透水水泥混凝土路面技术规程.pdf
- 第二章第五节 跨学科实践:制作隔音房间模型-人教版2024物理八年级上学期.pptx
- [股市论谈]53万打天下(53万实盘帐户天天更新).t
- 第9课 创新增才干-【中职专用】2024年中职思想政治《哲学与人生》金牌课件(高教版2023·基础模块).pptx VIP
- 纲要(上)第20课 五四运动与中国共产党的诞生课件(共23张PPT).pptx VIP
文档评论(0)