• 邻接表模型中的节点移动


    邻接表模型中的节点移动

    邻接表模型:http://www.cnblogs.com/ac1985482/p/Managing-Hierarchical-Data-in-MySQL.html

    此文中详细的描述了邻接表模型中的各种查询,对于层级结构,可以用一条sql语句就能将它查询出来。
    使用最多的就是查目录,比如查询id为10的所有父级节点

    select a.* from node a,node b where a.lft <b.lft and a.rgt >b.lft and b.id=10;
    

    这种情况的查询,在邻接表模型的文章中已经说明的非常详细了。我这里主要是写邻接表节点移动的操作。邻接表的移动需要把一个节点和子节点看成一个整体的移动。主要思路如下:

    假设将id为m的节点移动的节点n的后面

    1. 将$n后面的位置扩大 $step= m.rgt -m.lft +1 的空间o。

    2. 将对m执行sql,移动到n的后面,并记录 LFT=m.lft RGT=m.rgt

    3. 移除空出来的空间

    我的使用环境前端使用了一个ztree的js插件,在onDrop事件中反馈了移动的位置。一下为PHP的代码:

    代码

    // 查找targeNode
    $targeQuery=$this->db->query("select * from category_edit_node where id=$targeNode"); 
    $targeNode=$targeQuery->row();
    
    if (!$targeQuery)
        return false; 
    
    //查找$node 的步长 
    $query=$this->db->query("select rgt-lft a from category_edit_node where id=$node"); 
    $row=$query->row(); 
    if (!$row)
       return false; 
    
    $step=$row->a+1;//move node 需要的占用的宽度  
    
    //1.将目标位置扩大step的大小 ,这里的type为与targeNode相对的节点
    // $type "inner":成为子节点,"prev":成为同级前一个节点,"next":成为同级后一个节点
    $targe=0;
    if ($type=="inner"){
      $targe=$targeNode->lft;
    }
    if($type=="prev"){
     $targe=$targeNode->lft-1;
    }
    if ($type=="next"){
    $targe=$targeNode->rgt;
    } 
     
    //开始事务
    $this->db->trans_start();
    //将需要移动到的位置空出来。
    $this->db->query("update category_edit_node set lft=lft +$step where lft>$targe and fid=$id");
    $this->db->query("update category_edit_node set rgt=rgt+$step where rgt>$targe and fid=$id");
    
    //获取扩大后的node
    $query=$this->db->query("select rgt,depth from category_edit_node where id=$node "); 
    $row=$query->row();
    $rgt=$row->rgt;
    if ($type=="inner"){
    	$depth=$targeNode->depth+1;
    }else{
    	$depth=$targeNode->depth;
    } 
    
    //2. 将node节点和子节点的lft rgt修改到扩大的区间  
    $this->db->query(" update category_edit_node a,category_edit_node b  
    	set a.lft=a.lft-b.lft+$targe+1,a.rgt=a.rgt-b.lft+$targe+1,a.depth=a.depth-b.depth+$depth
    	where a.fid=$id and b.fid=$id and a.lft >=b.lft and a.lft <b.rgt  and b.id=$node;");
    
    //3. 收缩空出来的位置 
    
    $this->db->query("update category_edit_node set lft =lft-$step where lft >$rgt and fid=$id");
    $this->db->query("update category_edit_node set rgt =rgt -$step where rgt >$rgt and fid=$id");
    
    $this->db->trans_complete();
    
    if ($this->db->trans_status() === FALSE) {
     return false;
    }else{
     return true;
    }
  • 相关阅读:
    Fastboot的使用简单教程
    Spoj 2713 Can you answer these queries IV 水线段树
    互联网金融中的各条路子
    MySql事务无法回滚的原因
    Html 语法学习笔记二
    谈长耗时任务的优化
    收藏:左路Deep Learning+右路Knowledge Graph,谷歌引爆大数据
    [ javascript ] 司徒正美的fadeOut-fadeIn效果!
    顺序队列
    Linux下oracle开机自启动服务
  • 原文地址:https://www.cnblogs.com/ac1985482/p/3936693.html
Copyright © 2020-2023  润新知