数据库中避免树形结构出现回环图_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 数据库中避免树形结构出现回环图

数据库中避免树形结构出现回环图

 2015/4/11 0:48:33  Gozs_cs_dn  程序员俱乐部  我要评论(0)
  • 摘要:Q:以最简单的表结构设计出符合需求的组织架构?A:组织架构通常是树形结构,上级包含下级所有权限。因此表结构可以如下设计:+----+------+--------+|ID|NAME|parent|+----+------+--------+其中parent为外键列,引用指向当前表ID,同时约束CHECK(ID<>parent)来确保数据的有效性。Q:是否可以仅通过一条SQL获取指定ID的所有子集列表?A:不能。一条SQL只能在数据库执行一次,SQL仅具备常规逻辑(与[and]
  • 标签:数据库 数据

Q:以最简单的表结构设计出符合需求的组织架构
A:组织架构通常是树形结构,上级包含下级所有权限。因此表结构可以如下设计:
            +----+------+--------+
            | ID | NAME | parent |
            +----+------+--------+
            其中parent为外键列,引用指向当前表ID,同时约束CHECK(ID <> parent) 来确保数据的有效性。

Q:是否可以仅通过一条SQL获取指定ID的所有子集列表?
A:不能。一条SQL只能在数据库执行一次,SQL仅具备常规逻辑(与[and], 或[or, in, not in], 非[is null, is not null])能力不具备如循环递归等能力,所以不能直接通过一条SQL语句获取到所有需要的数据;因此要获取子集列表只能通过程序控制;

Q:如何获取子集列表?
A:可以有两种选择:
  1、使用数据库支持的存储过程(Procedure);
  2、使用编程语言(如:Java,C#,PHP等,该文以Java为例)循环实现;
  对比:
   +----+--------+----------------+
   |    |    Procedure    | PL(Programming Languages) |
   +----+--------+----------------+
   |    优点   | 减少SQL传输 | 语言性能更强,更容易控制   |
   +----+--------+----------------+
   |    缺点   | 增加DB响应时间 |   层次深、节点多时,SQL发 |
   |    |        |    送次数不确定      |
   +----+--------+----------------+
   递归层次3层以下且分支在2条左右可以使用PL实现,在此作者推荐Procedure方式实现;

Q:如何避免在树架构中出现图架构(回环)?
A: 关于这个问题,作者和同事在初时也是头疼不已;如何规避树结构夹杂图结构主要由以下两方面入手:
   第一、数据插入前,递归(循环) 验证目标节点(TN--Target Node)未出现在准父级( FTB--Father-To-Be)的父节点列表中;从 TN->FTB 是不好查询的,而反过来则要容易得多:FBT->TN;
   第二、为防止DB(数据库) 被通过非法途径污染架构树,在获取子集时也需要做验证(FBT->TN);
    *第三、设置插入触发器(IT--Insert Trigger),更新触发器(UT--Update Trigger),在触发器中验证 FBT->TN合法性;
    第四、经研究讨论后,发现一种更有效的方式避免在树结构中出现图结构:
        为树结构中的每个节点定义层级概念!
            +----+------+--------+-------+
            | ID | NAME | parent | Level |
            +----+------+--------+-------+
    | 1  | name1|  null  |  null |
            +----+------+--------+-------+
    | 2  | name2|   1    |   2   |
            +----+------+--------+-------+ 
    | 3  | name3|   1    |   2   |
            +----+------+--------+-------+ 
    | 4  | name4|  null  |  null |
            +----+------+--------+-------+ 
    | 5  | name5|   3    |   3   |
            +----+------+--------+-------+ 
     需求:1、将ID(3)父节点修改为ID(2).          a:获取ID(2)层级值(L2)
          b:获取ID(3)层级值(L3)
          c:验证ID(3)与ID(2)层级关系,被移动节点不能高于目标节点(L3>L2)
          d:获取L3需被提升的层次:DV=L3-L2-1 (DV--Difference  Value)

          e:修改以ID(3)为根的所有子节点(包括ID(3))层次都提升
        2、将ID(4)父节点分配为ID(3).
          a:获取ID(3) 层级值(L3)
          b:将L4修改为L3+1后完成操作
        3、将ID(5)父节点修改为ID(4).
          a:获取ID(4)层级值L4
          b:获取ID(5)层级值L5
          c:ID(5)不是根节点(L5<>1),设置L4=L5-1
          d:ID(5)是根节点,设置L4=1同时修改以ID(5)为根的所有子节点(包括ID(5))层次都降低1
上一篇: activiti源码解读之心得整编 下一篇: 没有下一篇了!
发表评论
用户名: 匿名