没有合适的资源?快使用搜索试试~ 我知道了~
7 1/4/6/7/ 解决了 路径枚举的优点: 对于以上表,假设我们需要查询某个节点的全部祖先,SQL语句可以这样写(假设查询7的所有祖先节
资源详情
资源评论
资源推荐
一、邻接表:依赖父节点
邻接表的方案如下(仅仅说明问题):
CREATE TABLE Comments(
CommentId int PK,
ParentId int, --记录父节点
ArticleId int,
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
剩余13页未读,继续阅读
丛乐
- 粉丝: 31
- 资源: 312
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0