大大毛 的笔记

  DDM's Note

哪怕没有办法一定有说法,
就算没有鸽子一定有乌鸦,
固执无罪 梦想有价,
让他们惊讶.

posts - 14, comments - 23, trackbacks - 0, articles - 58
   :: 首页 ::  :: 联系 ::  :: 管理

树型结构的处理

Posted on 2006-10-15 03:16 大大毛 阅读(872) 评论(0)  编辑  收藏 所属分类: SQL
   树型结构在应用中被广泛的运用,在数据操作上需要一定的技巧来进行处理:

   在表结构的定义上,有多种方式可以采用。
  .数据表:
      a.单向链表式的结构 ( 这是藕给它起的名称,因为它与链表的结构相似,除了必要的自身描述外,就只包含父节点的位置)
         DDL示例:
--相当于单向链表
create table linkTree (
    id 
varchar(10primary key,         --节点自身ID
    nodeContent varchar(50),          --节点内容
    parentId varchar(10default ''    --父节点ID
)

         优点
            .列宽固定,表结构易维护;
            .查找指定节点的上/下游节点效率高;
            .维护树型结构方便(增/删层);
         缺点,如在下列情况中,都需要多次Select完成:
            .从指定节点开始列出全部子树 ( 除 Oracle 提供支持外 );
            .返回从指定节点A到其子节点B的路径 ( B 与 A 的层数相差会大于 1 );

         DML示例:
            向下查找及统计子节点(仅一层)
            (1)通过父节点的ID
通过父节点的ID

            (2)通过父节点的内容
条件列nodeContent上存在唯一性约束

               由于条件列无唯一性约束,所以在查找时有可能会返回一个记录集,需要做一些处理:
条件列nodeContent上无唯一性约束

            (3)查找兄弟节点
查找兄弟节点

            (4)遍历树
            由于链表式表结构的特点,决定了无法用通用的单次 Select 完成操作,对于不同的 DBMS 可以采取不同的策略:
            如Oracle
               select * from linkTree start with id='00' connect by PRIOR  id = parentId;
            如Ms-SQL2000
               表的结构决定了数据只能逐层查找,网上常见的有使用存储过程进行递归返回表变量来实现。
               这里我用循环的方式来实现,效率比递归+表变量要高。
Ms-SQL2000遍历树
      注:这里引入一个site列,是为了能够在输出时更加好的进行排序,因为在最终输出至网页时很有可能是顺序向下输出的,这里正好体现出这种结构。

      b.位置描述式的结构 ( 这是藕给它起的名称,它有一个列,该列描述了当前节点在树中的位置)
         DDL示例:
create table siteTree (
    id 
varchar(2primary key,
    nodeContent 
varchar(20),
    site 
varchar(200)
)

         例子
            01      Root      01
            02      dep1      0102
            03      dep2      0103
            04      dep11    010201

         优点
            由于该表结构中带一个位置描述列site,因此对于关于树的遍历等问题的解决将变得异常的轻松。位置列按从根结点到当前结点的ID连接而成。

         缺点
            有利即有弊,位置描述列也同时突出该种结构的缺点,它最大的缺点就是树的层次不可能是无穷的,由于它由整个路径的ID连接而已,因此该列的宽度并不是固定的,如根节点的长度将是ID列的宽度,而当前节点位置列所需要空间 = 当前节点层次 * ID列宽度。
            针对链表式结构的优点,这里就成了缺点,层次间的增删将变得较为困难。

         遍历树:
--输出指定节点的全部子节点
select * from siteTree where CHARINDEX('00',site)=1 order by site



只有注册用户登录后才能发表评论。


网站导航:
 

i am ddm