邻接表模型中的节点移动

邻接表模型中的节点移动

邻接表模型: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;
}
原文地址:https://www.cnblogs.com/ac1985482/p/3936693.html