zoukankan      html  css  js  c++  java
  • 数据库中树状关系(各种树状分类)的查找

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

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

    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;其所有子节点的的左右值均小于此节点的左右值。
    • 反之则节点为叶节点。

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

    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示例:

    <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>
  • 相关阅读:
    关于拷贝构造函数和赋值运算符
    笔试题(转)
    Pro *C/C++学习笔记(一)
    __cdecl
    Visual Studio 2010中C++的四大变化(转)
    小小递归函数的执行过程
    stl string常用函数
    【C/C++ string】之strcpy函数
    409 Excuses, Excuses!
    10878 Decode the tape
  • 原文地址:https://www.cnblogs.com/hangxin1940/p/2092628.html
Copyright © 2011-2022 走看看