1. 程式人生 > >mysql 無限級分類

mysql 無限級分類

ble 包含 each highlight update 名稱 ray 是否 script

兩種思路吧,遞歸 和 非遞歸

遞歸

$arr = [
    1=>[‘id‘=>1,‘pid‘=>0],
    2=>[‘id‘=>2,‘pid‘=>0],
    3=>[‘id‘=>3,‘pid‘=>1],
    4=>[‘id‘=>4,‘pid‘=>1],
    5=>[‘id‘=>5,‘pid‘=>0],
    6=>[‘id‘=>6,‘pid‘=>3],
    7=>[‘id‘=>7,‘pid‘=>6],
    8=>[‘id‘=>8,‘pid‘=>3],
    9=>[‘id‘=>9,‘pid‘=>4],
    10=>[‘id‘=>10,‘pid‘=>7],
    11=>[‘id‘=>11,‘pid‘=>7],
];

//排序數組arr 層數level  鍵val
function display_test($arr,$level,$val){

    if($level==0)
    {
        echo "頂級目錄\n";
    }else{
        echo str_repeat(‘    ‘,$level).$arr[$val][‘id‘]."\n";
    }
    $temp = get($arr,$val);
    foreach ($temp as $v)
    {
        display_test($arr,$level+1,$v[‘id‘]);
    }
}

//獲取 pid的所有下一級子節點
function get($arr,$pid)
{
    $res = [];
    foreach ($arr as $v)
    {
        if($v[‘pid‘]==$pid)
        {
            $res[] = $v;
        }
    }
    return $res;
}

display_test($arr,0,0);die;

  

非遞歸 左右值法

表結構

CREATE TABLE `sys_department` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL COMMENT ‘部門名稱‘,
  `description` varchar(200) DEFAULT NULL COMMENT ‘描述‘,
  `create_time` int(11) DEFAULT NULL COMMENT ‘添加時間‘,
  `left_value` int(11) DEFAULT NULL,
  `right_value` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT=‘部門表‘

  

添加新下級:用事物

//修改右值
            $sql = "UPDATE {$this->table} SET right_value = right_value+2 WHERE right_value>=:right_value";

//修改左值
            $sql = "UPDATE {$this->table} SET left_value = left_value+2 WHERE left_value>=:left_value";

//插入
$sql = "INSERT INTO {$this->table}(name,description,left_value,right_value,create_time) VALUES(:name,:description,:left_value,:right_value,:create_time)";

  

刪除節點: 用事物

//刪除
        $sql = "DELETE FROM {$this->table} WHERE left_value>=:left_value AND right_value<=:right_value";

//修改左值
            $sql = "UPDATE {$this->table} SET left_value=left_value-{$offset} WHERE left_value>:left_value";

//修改右值
            $sql = "UPDATE {$this->table} SET right_value=right_value-{$offset} WHERE right_value>:right_value";

  

獲取所有節點,包含縮進

public function display_tree($id){
    //獲取節點
        $model = $this->model->getById($id);
        if(!$model)
        {
            return false;
        }
        $left = $model[‘left_value‘];
        $right = $model[‘right_value‘];

//獲取子節點  按left_value排序 
        $res = $this->getByLeftRight($left,$right);
        $temp = [];
//循環找出節點所在級數
        foreach ($res as $k=>$v)
        {
            if(count($temp)>0)
            {
                // 檢查我們是否應該將節點移出堆棧
                while ($temp[count($temp) - 1] < $v[‘right_value‘]) {
                    array_pop($temp);
                }
            }
            //echo str_repeat("*",count($temp)).$v[‘name‘]."\n";
            $res[$k][‘level‘] = count($temp);
            $temp[] = $v[‘right_value‘];
        }
        //level 第幾層
        return $res;
    }    

  

mysql 無限級分類