数据库中树状关系(各种树状分类)的查找

很多情况下,一些树状分类关系的都使用递归来查询,用递归来显示,如果数据量大的话,会造成各种麻烦。

我们可以使用树,用先序遍历来代替递归,如表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
create table category
(
    id varchar(40) primary key,
    name varchar(100),
    lft int,
    rgt int
);
insert into category values('1','商品',1,18);
insert into category values('2','平板电视',2,7);
insert into category values('3','冰箱',8,11);
insert into category values('4','笔记本',12,17);
insert into category values('5','长虹',3,4);
insert into category values('6','索尼',5,6);
insert into category values('7','西门子',9,10);
insert into category values('8','thinkpad',13,14);
insert into category values('9','dell',15,16);

 

先序遍历的顺序图:

clip_image001[9]

 

可以发现规律:

  • 如果一个节点存在子节点,那么右值与左值之差不为1;其所有子节点的的左右值均小于此节点的左右值。
  • 反之则节点为叶节点。

 

在数据库中的查询语句如下:

1
2
3
4
5
select child.name,count(child.name) depth from category parent,category child where child.lft>=parent.lft and child.rgt<=parent.rgt group by child.name order by child.lft;
--首先将一个表看成两个表,一张是父节点,一张是子节点
--子节点的左值小于父节点的左值,右值小于父节点的右值,根据这个条件获得存在关系的数据
--对子节点的name进行归组,然后统计个数(count),这样得到有几个上级结点,也就是层次(depth)
--最后,按照子节点的左值进行排序

这样,会以很高的效率查询出树状结构,避免了递归的缺点。

 

 

在交互层面,列举一个jsp的js示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<html>
  <head>
    <title>树状结构</title>
 
    <!-- 这里使用了xtree -->
    <script src="${pageContext.request.contextPath }/js/xtree.js"></script>
    <link type="text/css" rel="stylesheet" href="${pageContext.request.contextPath }/css/xtree.css">
 
  </head>
   
  <body>
       
      <script type="text/javascript">
          <c:forEach var="c" items="${list}">
            //这是根结点
              <c:if test="${c.depth==1}">
               var tree = new WebFXTree('${c.name}');
               tree.target="right";
               tree.action = "${pageContext.request.contextPath}/servlet/AddChildServlet?id=${c.id}";
              </c:if>
 
            //这是二级结点
              <c:if test="${c.depth==2}">
                  var node${c.depth} = new WebFXTreeItem('${c.name}');
                  node${c.depth}.target="right";
                  node${c.depth}.action = "${pageContext.request.contextPath}/servlet/AddChildServlet?id=${c.id}";
                  tree.add(node${c.depth});
              </c:if>
 
            //如果深度大于2级了,直接在node名称上做手脚
              <c:if test="${c.depth>2}">
                      var node${c.depth} = new WebFXTreeItem('${c.name}');
                      node${c.depth}.target="right";
                      node${c.depth}.action = "${pageContext.request.contextPath}/servlet/AddChildServlet?id=${c.id}";
                       node${c.depth-1}.add(node${c.depth});
              </c:if>
          </c:forEach>
           
          document.write(tree);
      </script>
   
  </body>
</html>

posted on   黑暗伯爵  阅读(1149)  评论(0编辑  收藏  举报

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述

导航

< 2011年6月 >
29 30 31 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 1 2
3 4 5 6 7 8 9

统计

点击右上角即可分享
微信分享提示