mysql无限极分类

推荐两种MySQL无限级分类设计方案 软件开发过程中我们经常会遇到各种各样多级的数据结构需求。刚开始与产品沟通的最多只支持3级。后期根据需求的迭代3级变成多级再变成无限级。有时候产品为了减少麻烦产品初级就会定义支持无限的分类结构。分类的产品需求非常简单可能就一句话支持无限级的分类数据结构。但分类的代码开发繁琐麻烦有时候还有点复杂。今天为大家介绍两种无限级分类设计方案。大家可以根据自身的业务需求合理使用解决方案。第一种方案:父ID方式1... 阅读详情

CREATE TABLE `tree` (
  `id` INT(10) NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(255) NOT NULL,
  `lft` INT(10) NOT NULL DEFAULT '0' COMMENT '左节点',
  `rgt` INT(10) NOT NULL DEFAULT '0' COMMENT '右节点',
  `status` INT(1) NOT NULL DEFAULT '0' COMMENT '逻辑删除 1是 0否',
  PRIMARY KEY (`id`),
  KEY `lft` (`lft`),
  KEY `rgt` (`rgt`),
  KEY `status` (`status`)
) ENGINE=INNODB  DEFAULT CHARSET=utf8;

第一个节点
INSERT INTO tree VALUES (NULL, 'A', 0, 1, 0);
SELECT * FROM tree

$a_l = 0; $a_r = 1;
第二个节点(A的子节点)
UPDATE tree SET lft = lft + 2 WHERE lft > 1;#lft > $a_r
UPDATE tree SET rgt = rgt + 2 WHERE rgt >= 1;#rgt >= $a_r
INSERT INTO tree VALUES (NULL, 'B', 1, 1+1, 0);#(NULL, 'B', $a_r, $a_r + 1, 0);

$a_l = 0; $a_r = 3;
第三个节点(A的子节点)
UPDATE tree SET lft = lft + 2 WHERE lft > 3;#lft > $a_r
UPDATE tree SET rgt = rgt + 2 WHERE rgt >= 3;#rgt >= $a_r
INSERT INTO tree VALUES (NULL, 'C', 3, 3+1, 0);#(NULL, 'C', $a_r, $a_r + 1, 0);

$a_l = 0; $a_r = 5;
第四个节点(A的子节点)
UPDATE tree SET lft = lft + 2 WHERE lft > 5;#lft > $a_r
UPDATE tree SET rgt = rgt + 2 WHERE rgt >= 5;#rgt >= $a_r
INSERT INTO tree VALUES (NULL, 'D', 5, 5+1, 0);#(NULL, 'D', $a_r, $a_r + 1, 0);

$b_l = 1; $b_r = 2;
第五个节点(B的子节点)
UPDATE tree SET lft = lft + 2 WHERE lft > 2;#lft > $b_r
UPDATE tree SET rgt = rgt + 2 WHERE rgt >= 2;#rgt >= $b_r
INSERT INTO tree VALUES (NULL, 'E', 2, 2+1, 0);#(NULL, 'E', $b_r, $b_r + 1, 0);

$b_l = 1; $b_r = 4;
第六个节点(B的子节点)
UPDATE tree SET lft = lft + 2 WHERE lft > 4;#lft > $b_r
UPDATE tree SET rgt = rgt + 2 WHERE rgt >= 4;#rgt >= $b_r
INSERT INTO tree VALUES (NULL, 'F', 4, 4+1, 0);#(NULL, 'F', $b_r, $b_r + 1, 0);

$e_l = 2; $e_r = 3;
第六个节点(E的子节点)
UPDATE tree SET lft = lft + 2 WHERE lft > 3;#lft > $e_r
UPDATE tree SET rgt = rgt + 2 WHERE rgt >= 3;#rgt >= $e_r
INSERT INTO tree VALUES (NULL, 'G', 3, 3+1, 0);#(NULL, 'G', $e_r, $e_r + 1, 0);

$e_l = 2; $e_r = 5;
删除节点(E节点)
$v = 5 - 2 + 1 = 4;#$v = $e_r - $e_l + 1; 
DELETE FROM tree WHERE lft >= 2 AND rgt <= 5;#lft >= $e_l and rgt <= $e_r
UPDATE tree SET lft = lft - 4 WHERE lft > 2;#lft = lft - $v where lft > $e_l
UPDATE tree SET rgt = rgt - 4 WHERE rgt > 5;#rgt = rgt - $v WHERE rgt > $e_r

$b_l = 1; $b_r = 4;
删除节点(B节点)
$v = 4 - 1 + 1 = 4;#$v = $b_r - $b_l + 1; 
DELETE FROM tree WHERE lft >= 1 AND rgt <= 4;#lft >= $b_l and rgt <= $b_r
UPDATE tree SET lft = lft - 4 WHERE lft > 1;#lft = lft - $v where lft > $b_l
UPDATE tree SET rgt = rgt - 4 WHERE rgt > 4;#rgt = rgt - $v WHERE rgt > $b_r

总结:
一、根节点
lft=0,rgt=1
二、添加子节点:
找到父节点的右值$p_r,所有节点左值 > $p_r 的左值 + 2;所有节点右值 >= $p_r的右值 +2;插入新节点lft=$p_r,rgt=$p_r + 1;
三、删除节点:
找到所要删除节点的左右值$del_l,$del_r,删除所有左值>=$del_l,右值<=$del_r的节点;计算$v = $del_r - $del_l + 1;修改节点左值 > $del_l的左值为lft = lft - $v;修改节点右值 > $del_r 的右值为rgt = rgt - $v
四、获取子节点
1、不包含自己lft > $current_l and rgt < $current_r
2、包含自己lft >= $current_l and rgt <= $current_r
3、不包含自己的所有父类 lft < $current_l and rgt > $current_r
4、包含自己的所有父类 lft <= $current_l and rgt >= $current_r
五、计算子节点的数量
($current_r - $current_l - 1)/2
六、叶子节点
rgt = lft + 1
七、树的深度
SELECT node.*, (COUNT(parent.name) - 1) AS deep FROM tree AS node,tree AS parent WHERE node.lft BETWEEN parent.lft AND parent.rgt GROUP BY node.name ORDER BY node.lft 
八、检索单一路径
SELECT parent.* FROM tree AS node, tree AS parent WHERE node.lft BETWEEN parent.lft AND parent.rgt AND node.name = 'E' ORDER BY parent.lft;
九、获取直接子节点
SELECT * FROM (SELECT node.*, (COUNT(parent.name) - 1) AS deep FROM tree AS node,tree AS parent WHERE node.lft BETWEEN parent.lft AND parent.rgt GROUP BY node.name ORDER BY node.lft ) AS a WHERE a.deep<= 1;

 

<?php

/**
 * 基于左右值排序的无限分类算法 
 * 数据库结果为 
  CREATE TABLE om_catagory (
  CatagoryID int(10) unsigned NOT NULL auto_increment,
  Name varchar(50) default '',
  Lft int(10) unsigned NOT NULL default '0',
  Rgt int(10) unsigned NOT NULL default '0',
  PRIMARY KEY (id),
  KEY lft (lft),
  KEY rgt (rgt)
  )
 */
class sortclass {

    /**
     * Description 
     * @var        
     * @since     1.0 
     * @access    private 
     */
    var $db;

    /**
     * Description 
     * @var        
     * @since     1.0 
     * @access    private 
     */
    var $tablefix;

    /**
     * Short description.  
     * 构造函数,引入数据库操作类函数 
     * Detail description 
     * @param      none 
     * @global     none 
     * @since      1.0 
     * @access     private 
     * @return     void 
     * @update     date time 
     */
    function sortclass() {
        global $db;
        $this->db = $db;
        $this->tablefix = "om_";
    }

// end func  

    /**
     * Short description.  
     * 增加新的分类 
     * Detail description 
     * @param      none 
     * @global     none 
     * @since      1.0 
     * @access     private 
     * @return     void 
     * @update     date time 
     */
    function addsort($CatagoryID, $SortName) {
        if ($CatagoryID == 0) {
            $Lft = 0;
            $Rgt = 1;
        } else {
            $Result = $this->checkcatagory($CatagoryID);
            //取得父类的左值,右值  
            $Lft = $Result['Lft'];
            $Rgt = $Result['Rgt'];
            $this->db->query("UPDATE `" . $this->tablefix . "catagory` SET `Lft`=`Lft`+2 WHERE `Lft`>$Rgt");
            $this->db->query("UPDATE `" . $this->tablefix . "catagory` SET `Rgt`=`Rgt`+2 WHERE `Rgt`>=$Rgt");
        }

//插入  
        if ($this->db->query("INSERT INTO `" . $this->tablefix . "catagory` SET `Lft`='$Rgt',`Rgt`='$Rgt'+1,`Name`='$SortName'")) {
            //$this->referto("成功增加新的类别","JAVASCRIPT:HISTORY.BACK(1)",3);  
            return 1;
        } else {
            //$this->referto("增加新的类别失败了","JAVASCRIPT:HISTORY.BACK(1)",3);  
            return -1;
        }
    }

// end func  

    /**
     * Short description.  
     * 删除类别 
     * Detail description 
     * @param      none 
     * @global     none 
     * @since      1.0 
     * @access     private 
     * @return     void 
     * @update     date time 
     */
    function deletesort($CatagoryID) {
//取得被删除类别的左右值,检测是否有子类,如果有就一起删除  
        $Result = $this->checkcatagory($CatagoryID);
        $Lft = $Result['Lft'];
        $Rgt = $Result['Rgt'];
//执行删除  
        if ($this->db->query("DELETE FROM `" . $this->tablefix . "catagory` WHERE `Lft`>=$Lft AND `Rgt`<=$Rgt")) {
            $Value = $Rgt - $Lft + 1;
            //更新左右值  
            $this->db->query("UPDATE `" . $this->tablefix . "catagory` SET `Lft`=`Lft`-$Value WHERE `Lft`>$Lft");
            $this->db->query("UPDATE `" . $this->tablefix . "catagory` SET `Rgt`=`Rgt`-$Value WHERE `Rgt`>$Rgt");
            //$this->referto("成功删除类别","javascript:history.back(1)",3);  
            return 1;
        } else {
            //$this->referto("删除类别失败了","javascript:history.back(1)",3);  
            return -1;
        }
    }

// end func  

    /**
     * Short description.  
     * 1,所有子类,不包含自己;2包含自己的所有子类;3不包含自己所有父类4;包含自己所有父类 
     * Detail description 
     * @param      none 
     * @global     none 
     * @since      1.0 
     * @access     private 
     * @return     void 
     * @update     date time 
     */
    function getcatagory($CatagoryID, $type = 1) {
        $Result = $this->checkcatagory($CatagoryID);
        $Lft = $Result['Lft'];
        $Rgt = $Result['Rgt'];
        $SeekSQL = "SELECT * FROM `" . $this->tablefix . "catagory` WHERE ";
        switch ($type) {
            case "1":
                $condition = "`Lft`>$Lft AND `Rgt`<$Rgt";
                break;
            case "2":
                $condition = "`Lft`>=$Lft AND `Rgt`<=$Rgt";
                break;
            case "3":
                $condition = "`Lft`<$Lft AND `Rgt`>$Rgt";
                break;
            case "4":
                $condition = "`Lft`<=$Lft AND `Rgt`>=$Rgt";
                break;
            default :
                $condition = "`Lft`>$Lft AND `Rgt`<$Rgt";
                ;
        }
        $SeekSQL .= $condition . " ORDER BY `Lft` ASC";
        $Sorts = $this->db->getrows($SeekSQL);
        return $Sorts;
    }

// end func  

    /**
     * Short description.  
     * 取得直属父类 
     * Detail description 
     * @param      none 
     * @global     none 
     * @since      1.0 
     * @access     private 
     * @return     void 
     * @update     date time 
     */
    function getparent($CatagoryID) {
        $Parent = $this->getcatagory($CatagoryID, 3);
        return $Parent;
    }

// end func  
    /**
     * Short description.  
     * 移动类,如果类有子类也一并移动 
     * Detail description 
     * @param      none 
     * @global     none 
     * @since      1.0 
     * @access     private 
     * @return     void 
     * @update     date time 
     */

    function movecatagory($SelfCatagoryID, $ParentCatagoryID) {
        $SelfCatagory = $this->checkcatagory($SelfCatagoryID);
        $NewCatagory = $this->checkcatagory($ParentCatagoryID);

        $SelfLft = $SelfCatagory['Lft'];
        $SelfRgt = $SelfCatagory['Rgt'];
        $Value = $SelfRgt - $SelfLft;
//取得所有分类的ID方便更新左右值  
        $CatagoryIDS = $this->getcatagory($SelfCatagoryID, 2);
        foreach ($CatagoryIDS as $v) {
            $IDS[] = $v['CatagoryID'];
        }
        $InIDS = implode(",", $IDS);

        $ParentLft = $NewCatagory['Lft'];
        $ParentRgt = $NewCatagory['Rgt'];
//print_r($InIDS);  
//print_r($NewCatagory);  
//print_r($SelfCatagory);  
//exit;  
        if ($ParentRgt > $SelfRgt) {
            $UpdateLeftSQL = "UPDATE `" . $this->tablefix . "catagory` SET `Lft`=`Lft`-$Value-1 WHERE `Lft`>$SelfRgt AND `Rgt`<=$ParentRgt";
            $UpdateRightSQL = "UPDATE `" . $this->tablefix . "catagory` SET `Rgt`=`Rgt`-$Value-1 WHERE `Rgt`>$SelfRgt AND `Rgt`<$ParentRgt";
            $TmpValue = $ParentRgt - $SelfRgt - 1;
            $UpdateSelfSQL = "UPDATE `" . $this->tablefix . "catagory` SET `Lft`=`Lft`+$TmpValue,`Rgt`=`Rgt`+$TmpValue WHERE `CatagoryID` IN($InIDS)";
        } else {
            $UpdateLeftSQL = "UPDATE `" . $this->tablefix . "catagory` SET `Lft`=`Lft`+$Value+1 WHERE `Lft`>$ParentRgt AND `Lft`<$SelfLft";
            $UpdateRightSQL = "UPDATE `" . $this->tablefix . "catagory` SET `Rgt`=`Rgt`+$Value+1 WHERE `Rgt`>=$ParentRgt AND `Rgt`<$SelfLft";
            $TmpValue = $SelfLft - $ParentRgt;
            $UpdateSelfSQL = "UPDATE `" . $this->tablefix . "catagory` SET `Lft`=`Lft`-$TmpValue,`Rgt`=`Rgt`-$TmpValue WHERE `CatagoryID` IN($InIDS)";
        }
        $this->db->query($UpdateLeftSQL);
        $this->db->query($UpdateRightSQL);
        $this->db->query($UpdateSelfSQL);
//$this->referto("成功移动类别","javascript:history.back(1)",3);  
        return 1;
    }

// end func  

    /**
     * Short description.  
     * 
     * Detail description 
     * @param      none 
     * @global     none 
     * @since      1.0 
     * @access     private 
     * @return     void 
     * @update     date time 
     */
    function checkcatagory($CatagoryID) {
//检测父类ID是否存在  
        $SQL = "SELECT * FROM `" . $this->tablefix . "catagory` WHERE `CatagoryID`='$CatagoryID' LIMIT 1";
        $Result = $this->db->getrow($SQL);
        if (count($Result) < 1) {
            $this->referto("父类ID不存在,请检查", "javascript:history.back(1)", 3);
        }
        return $Result;
    }

// end func  

    /**
     * Short description.  
     * 
     * Detail description 
     * @param      none 
     * @global     none 
     * @since      1.0 
     * @access     private 
     * @return     array($Catagoryarray,$Deep) 
     * @update     date time 
     */
    function sort2array($CatagoryID = 0) {
        $Output = array();
        if ($CatagoryID == 0) {
            $CatagoryID = $this->getrootid();
        }
        if (empty($CatagoryID)) {
            return array();
            exit;
        }
        $Result = $this->db->query('SELECT Lft, Rgt FROM `' . $this->tablefix .
                'catagory` WHERE `CatagoryID`=' . $CatagoryID);
        if ($Row = $this->db->fetch_array($Result)) {
            $Right = array();
            $Query = 'SELECT * FROM `' . $this->tablefix .
                    'catagory` WHERE Lft BETWEEN ' . $Row['Lft'] . ' AND ' .
                    $Row['Rgt'] . ' ORDER BY Lft ASC';

            $Result = $this->db->query($Query);
            while ($Row = $this->db->fetch_array($Result)) {
                if (count($Right) > 0) {
                    while ($Right[count($Right) - 1] < $Row['Rgt']) {
                        array_pop($Right);
                    }
                }
                $Output[] = array('Sort' => $Row, 'Deep' => count($Right));
                $Right[] = $Row['Rgt'];
            }
        }
        return $Output;
    }

// end func  

    /**
     * Short description.  
     * 
     * Detail description 
     * @param      none 
     * @global     none 
     * @since      1.0 
     * @access     private 
     * @return     void 
     * @update     date time 
     */
    function getrootid() {
        $Query = "SELECT * FROM`" . $this->tablefix . "catagory` ORDER BY `Lft` ASC LIMIT 1";
        $RootID = $this->db->getrow($Query);
        if (count($RootID) > 0) {
            return $RootID['CatagoryID'];
        } else {
            return 0;
        }
    }

// end func  
}

// end class  
?>

优化mysql左右值无限极分类

CREATE TABLE `tree` (
  `id` INT(10) NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(255) NOT NULL,
  `pid` INT(10) NOT NULL DEFAULT '0' COMMENT '父ID',
  `lft` INT(10) NOT NULL DEFAULT '0' COMMENT '左节点',
  `rgt` INT(10) NOT NULL DEFAULT '0' COMMENT '右节点',
  `level` INT(10) NOT NULL DEFAULT '0' COMMENT '深度',
  `status` INT(1) NOT NULL DEFAULT '0' COMMENT '逻辑删除 1是 0否',
  PRIMARY KEY (`id`),
  KEY `pid` (`pid`),
  KEY `lft` (`lft`),
  KEY `rgt` (`rgt`),
  KEY `level` (`level`),
  KEY `status` (`status`)
) ENGINE=INNODB  DEFAULT CHARSET=utf8;

第一个节点
INSERT INTO tree VALUES (NULL, 'A', 0, 0, 1, 0, 0);
SELECT * FROM tree

父节点左值$a_l = 0; 父节点右值$a_r = 1; 父节点深度$p_h=0; 父节点ID $pid=1
第二个节点(A的子节点)
UPDATE tree SET lft = lft + 2 WHERE lft > 1;#lft > $a_r
UPDATE tree SET rgt = rgt + 2 WHERE rgt >= 1;#rgt >= $a_r
INSERT INTO tree VALUES (NULL, 'B', 1, 1, 1+1, 0+1, 0);#(NULL, 'B', $pid, $a_r, $a_r + 1, $p_h + 1, 0);

$a_l = 0; $a_r = 3; 父节点深度$p_h=0; 父节点ID $pid=1
第三个节点(A的子节点)
UPDATE tree SET lft = lft + 2 WHERE lft > 3;#lft > $a_r
UPDATE tree SET rgt = rgt + 2 WHERE rgt >= 3;#rgt >= $a_r
INSERT INTO tree VALUES (NULL, 'C', 1, 3, 3+1, 0+1, 0);#(NULL, 'C', $pid, $a_r, $a_r + 1, $p_h + 1, 0);

$a_l = 0; $a_r = 5;父节点深度$p_h=0; 父节点ID $pid=1
第四个节点(A的子节点)
UPDATE tree SET lft = lft + 2 WHERE lft > 5;#lft > $a_r
UPDATE tree SET rgt = rgt + 2 WHERE rgt >= 5;#rgt >= $a_r
INSERT INTO tree VALUES (NULL, 'D', 1, 5, 5+1, 0+1, 0);#(NULL, 'D', $pid, $a_r, $a_r + 1, $p_h + 1, 0);

$b_l = 1; $b_r = 2;父节点深度$p_h=1; 父节点ID $pid=2
第五个节点(B的子节点)
UPDATE tree SET lft = lft + 2 WHERE lft > 2;#lft > $b_r
UPDATE tree SET rgt = rgt + 2 WHERE rgt >= 2;#rgt >= $b_r
INSERT INTO tree VALUES (NULL, 'E', 2, 2, 2+1, 1+1, 0);#(NULL, 'E', $pid, $b_r, $b_r + 1, $p_h + 1, 0);

$b_l = 1; $b_r = 4;父节点深度$p_h=1; 父节点ID $pid=2
第六个节点(B的子节点)
UPDATE tree SET lft = lft + 2 WHERE lft > 4;#lft > $b_r
UPDATE tree SET rgt = rgt + 2 WHERE rgt >= 4;#rgt >= $b_r
INSERT INTO tree VALUES (NULL, 'F', 2, 4, 4+1, 1+1, 0);#(NULL, 'F', $pid, $b_r, $b_r + 1, $p_h + 1, 0);

$e_l = 2; $e_r = 3;父节点深度$p_h=2; 父节点ID $pid=5
第七个节点(E的子节点)
UPDATE tree SET lft = lft + 2 WHERE lft > 3;#lft > $e_r
UPDATE tree SET rgt = rgt + 2 WHERE rgt >= 3;#rgt >= $e_r
INSERT INTO tree VALUES (NULL, 'G', 5, 3, 3+1, 2+1, 0);#(NULL, 'G', $pid, $e_r, $e_r + 1, $p_h + 1, 0);

$c_l = 9; $c_r = 10;父节点深度$p_h=1; 父节点ID $pid=3
第八个节点(C的子节点)
UPDATE tree SET lft = lft + 2 WHERE lft > 10;#lft > $c_r
UPDATE tree SET rgt = rgt + 2 WHERE rgt >= 10;#rgt >= $c_r
INSERT INTO tree VALUES (NULL, 'H', 3, 10, 10+1, 1+1, 0);#(NULL, 'G', $pid, $c_r, $c_r + 1, $p_h + 1, 0);

$e_l = 2; $e_r = 5;
删除节点(E节点)
$v = 5 - 2 + 1 = 4;#$v = $e_r - $e_l + 1; 
DELETE FROM tree WHERE lft >= 2 AND rgt <= 5;#lft >= $e_l and rgt <= $e_r
UPDATE tree SET lft = lft - 4 WHERE lft > 2;#lft = lft - $v where lft > $e_l
UPDATE tree SET rgt = rgt - 4 WHERE rgt > 5;#rgt = rgt - $v WHERE rgt > $e_r

$b_l = 1; $b_r = 4;
删除节点(B节点)
$v = 4 - 1 + 1 = 4;#$v = $b_r - $b_l + 1; 
DELETE FROM tree WHERE lft >= 1 AND rgt <= 4;#lft >= $b_l and rgt <= $b_r
UPDATE tree SET lft = lft - 4 WHERE lft > 1;#lft = lft - $v where lft > $b_l
UPDATE tree SET rgt = rgt - 4 WHERE rgt > 4;#rgt = rgt - $v WHERE rgt > $b_r

总结:
一、根节点
lft=0,rgt=1,level=0
二、添加子节点:
找到父节点的右值$p_r,所有节点左值 > $p_r 的左值 + 2;所有节点右值 >= $p_r的右值 +2;插入新节点lft=$p_r,rgt=$p_r + 1,level=p_level+1;
三、删除节点:
找到所要删除节点的左右值$del_l,$del_r,删除所有左值>=$del_l,右值<=$del_r的节点;计算$v = $del_r - $del_l + 1;修改节点左值 > $del_l的左值为lft = lft - $v;修改节点右值 > $del_r 的右值为rgt = rgt - $v
四、获取子节点
1、不包含自己lft > $current_l and rgt < $current_r
2、包含自己lft >= $current_l and rgt <= $current_r
3、不包含自己的所有父类 lft < $current_l and rgt > $current_r
4、包含自己的所有父类 lft <= $current_l and rgt >= $current_r
五、计算子节点的数量
($current_r - $current_l - 1)/2
六、叶子节点
rgt = lft + 1
七、树的深度
就是level
八、检索单一路径
E的
select * from tree where lft <= 2 and rgt >= 5
九、获取直接子节点
SELECT * FROM tree WHERE lft > 1 AND rgt < 8 AND LEVEL = 2

MySQL无限极分类数据表的设计 无限级分类表设计    实际上我们在开发过程中,就拿商品类别来说,它还可以有更多的延伸,我们先来举一个简单的例子,比如图书,他的下面还可以分小说、文学等,在小说下面还可以分为言情小说、科幻小说等,还可以再往下一级一级继续分,那么这种分类就属于无限极分类,那么无限极分类表该如何去设计,理论上说我们可以设计很多张表,但是随着分类的逐步增多,表的数目就会越来越多,所以无限极分类表往往采用另外一种形式。 阅读详情

相关推荐

[中级]微信开发工具与Gitee实现代码管理

微信开发工具-版本管理与Gitee实现代码管理同步更新

私信可回答各种问题~ 1511

数据库无限级分类

程序设计中常使用树型结构来表征某些数据的关联关系,如上下级、栏目结构、商品分类、菜单、回复等。 分类的层级关系可以表述为一父多子的继承关系,对应数据结构中的树。因此,分类问题可以转换为如何在数据库中存储一棵树。 常见树状结构 通常树形结构需借助数据库完成持久化,在关系型数据库中由于是以二维表的形式记录数据信息,因此不能直接将树形结构存入,必须设计合适的Schema及对应...

JunChow 754

mysql 无限级分类实现思路

第一种方案: 使用递归算法,也是使用频率最多的,大部分开源程序也是这么处理,不过一般都只用到四级分类。这种算法的数据库结构设计最为简单。category表中一个字段id,一个字段fid(父id)。这样可以根据WHERE id = fid来判断上一级内容,运用递归至最顶层。 分析:通过这种数据库设计出的无限级,可以说读取的时候相当费劲,所以大部分的程序最多3-4级分类,这就足以满足需求,从而一次性读出所有的数据,再对得到数组或者对象进行递归。本身负荷还是没太大问题。但是如果分类到更多级,那是不可取的办法。 这样看来这种分类有个好处,就是增删改的时候轻松了…然而就二级分类而言,采用这种算法就应该算

Mysql 无限分类3种方案

网上流传版 第一种方案:   使用递归算法,也是使用频率最多的,大部分开源程序也是这么处理,不过一般都只用到四级分类。这种算法的数据库结构设计最为简单。category表中一个字段id,一个字段fid(父id)。这样可以根据WHERE id = fid来判断上一级内容,运用递归至最顶层。   分析:通过这种数据库设计出的无限级,可以说读取的时候相当费劲,所以大部分的程序最多3-4级分类,这就...

weixin_34097242的博客 291

DTS中video-interfaces接口详解

视频数据管道通常由外部设备组成,例如通过I2C、SPI或UART总线控制的摄像机传感器,以及SoC内部IP块(包括视频DMA引擎和视频数据处理器)。 SoC内部块由DT节点描述,与其他SoC块放置方式类似。外部设备表示为它们各自总线控制器节点的子节点,例如I2C。 所有视频设备上的数据接口都由它们的子“port”节点描述。端口的配置取决于参与数据传输的其他设备,并由“endpoint”子节...

龙图腾的博客 9008

参考线平滑-FemPosDeviation-SQP

使用SQP(顺序二次规划)对离散点进行平滑

mpt0816的博客 2439

mysql无限极分类_mysql中无限极分类的代码实现

本篇文章给大家带来的内容是关于mysql中无限极分类的代码实现,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。我也是从别的地方找来的,分析后发现挺不错的,特来分享。无法发图只能简单处理:id name pid path1 ...

weixin_30610943的博客 711

从DeepMimic到虚拟偶像:用动作捕捉数据训练AI跳舞的完整流程(附Blender插件配置)

本文详细介绍了如何利用DeepMimic的深度强化学习框架,将动作捕捉数据转化为虚拟偶像或游戏角色的舞蹈动作。从核心的模仿学习理念、PyBullet环境搭建、策略网络与奖励函数设计,到数据处理、训练技巧(如参考状态初始化),最后讲解了如何将训练好的AI模型集成到Blender和Unity等工具中,实现从数据到实时驱动角色的完整流程。

weixin_29054399的博客 504

mysql 无限极 path_mysql中无限极分类的代码完成

软件安装:装机软件必备包SQL是Structured Query Language(结构化查询语言)的缩写。SQL是专为数据库而建立的操作命令集,是一种功能齐全的数据库语言。在使用它时,只需要发出“做什么”的命令,“怎么做”是不用使用者考虑的。SQL功能强大、简单易学、使用方便,已经成为了数据库操作的基础,并且现在几乎所有的数据库均支持SQL。本篇文章给大家带来的内容是关于mysql中无限极分类的...

weixin_36480303的博客 242

LeGo-LOAM源码篇:源码分析(3)

mapOptmization.cpp,主要内容包括回环检测、scan-to-map位姿优化、因子图。

slamml 1382

【图像拼接】源码精读:Parallax-Tolerant Unsupervised Deep Image Stitching(UDIS++)

注:Pytorch代码。【图像拼接论文精读】专栏对应文章【图像拼接】论文精读:Parallax-Tolerant Unsupervised Deep Image Stitching(UDIS++)配合对应的文章阅读,效果更佳!注:请重点关注代码段中的注释!!!有一些讲解的东西直接写在代码段的注释中了,同时多关注红色字体和绿色字体!!!我认为深度学习方法和传统方法有很多相似之处。比如:深度学习中的损失函数和传统方法中的对齐项、失真项等其实原理相同,只是求解方式不同。

主要更新底层视觉(去噪、超分等)相关的科研内容,形式为【论文精读】+【论文复现】 7274

mysql 无限极 path_mysql中无限极分类的代码实现

本篇文章给大家带来的内容是关于mysql中无限极分类的代码实现,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。我也是从别的地方找来的,分析后发现挺不错的,特来分享。无法发图只能简单处理:id name pid path1 ...

weixin_33525438的博客 217

工程测量不用愁,120个视频动画帮你忙,简单易学直观明了!

工程测量不用愁,120个视频动画帮你忙,简单易学直观明了!文末提供下载地址。 下载地址: 链接:https://pan.baidu.com/s/11S6XDq9Eaa3DG3VKRMBIPg

智慧空间实验室 1019

Mysql无限极分类 表结构设计

Mysql无限极分类 表结构设计 简介 所谓无限极,即有无限多层等级。例如云盘的目录结构,可以一级一级存储,无限嵌套;商品所属分类等. 实现 用mysql实现一个无限极存储其实就是实现一个链表结构,使用指针指向下一个节点,至少要包含3个字段:id,name,nextIndex,其中nextIndex用来指向下一层级。 例子 1.实现云盘目录结构存储,需两张表:image...

yun914的博客 2794

2024年游戏策划最新面试题及答案

1. **游戏策划**:负责游戏设计和开发的创意和技术过程。2. **主要职责**:设计游戏玩法、故事、角色、世界等。4. **游戏机制**:定义玩家如何与游戏世界互动的规则。13. **引人入胜的角色**:深入的背景故事、个性特征。3. **游戏平衡**:确保游戏公平、有趣且具有挑战性。7. **RPG特点**:角色发展、故事驱动、玩家选择。12. **关卡设计技巧**:挑战性、流动性、视觉引导。11. **游戏关卡设计**:创建游戏世界的不同阶段。5. **游戏循环**:玩家在游戏中重复的行为模式。

guo162308的博客 2320

05 - GRACE数据处理-球谐展开与球谐综合

GRACE数据处理-球谐展开和综合前面在介绍GRACE相关理论的时候提到过下面的公式,从公式形式上可以看出,面密度变化和球谐系数(CS)之间是能够相互转换的,那这个转化的过程可以称为球谐展开,简单理解就是将全球网格数据转化为球谐系数的过程。而球谐综合可以看作是球谐展开的逆过程,利用球谐系数计算到全球格网分布。

weixin_43339605的博客 1050

MySQL无限极分类表设计:实战项目中的高效解决方案

无限极分类表设计在实战项目中具有较高的实用性和效率性,能够很好地满足复杂层级关系数据的存储和查询需求。虽然存在一些缺点,但通过合理的数据维护和业务规划,可以有效降低其带来的影响。在实际应用中,我们可以根据具体的业务场景和数据特点,对这种设计进行适当的调整和优化,以达到最佳的使用效果。

zhaozhangxiao2的博客 864

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

无限极分类查询mysql_SQL无限极分类查询与上级ID查询命令

首先看一下mysql的这个函数CONCAT(str1,str2,…)返回结果为连接参数产生的字符串。如有任何一个参数为NULL ,则返回值为 NULL。或许有一个或多个参数。 如果所有参数均为非二进制字符串,则结果为非二进制字符串。 如果自变量中含有任一二进制字符串,则结果为一个二进制字符串。一个数字参数被转化为与之相等的二进制字符串格式;若要避免这种情况,可使用显式类型 cast, 例如: SE...

weixin_29029145的博客 1024

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

无限极分类查询mysql_关于使用sql语句实现无限极分类查询的疑问

如果只有这三级的话,可以这样自己和自己连表取语句为:select a.id as pid, a.name as pname, a.pid as ppid, b.name as ppnamefrom family a join family b on a.pid=b.id where a.id=儿子的信息的pid;实例:db83-3306>>select * from family;+-...

weixin_39634884的博客 131

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

无限极分类查询mysql_【MySQL】-无限极分类表设计与查询

What?举个简单的例子,我们设计购物商城之类的网站的时候一般商品都会有一级分类二级分类甚至三级分类或者再细分,如果按照传统思维我们可能会为每个级别的类别设置一张分类表然后再用外键去关联,虽然这样保证了没有冗余,但是我们完全没有必要设置这么多表,更何况商品类可以是无限细分的,我们不能因此而创建无数张表,最最重要的是这样多表连接查询时候会造成效率低下的问题,不利于性能的提升。这个时候我们如何只设置一...

weixin_36394468的博客 754

php无限极分类遍历时mysql语句_php无限极分类实现的两种解决方法

/*reader: 这是自己写的无限极分类实现方法 里面的编辑方法只是对分类名进行了编辑没有进行移动操作 小弟能力有限忘大家多多包涵啊第一种方法:CREATE TABLE `types` (`type_id` int(11) NOT NULL AUTO_INCREMENT,`type_name` varchar(20) NOT NULL,`type_p_id` varchar(64) NOT NU...

weixin_36053926的博客 222

mysql 无限极分类

1 import pymysql 2 class Type: 3 def __init__(self): 4 # 连接数据库 5 self.bankData = pymysql.connect("127.0.0.1", "root", "123123", "user") 6 # 设置字符编码 7 ...

weixin_30294295的博客 273

如何判断mysql_query是否成功,封装php无限极分类接口

针对update 语句等会对数据表进行修改的语句 在mysql_query($sql);后面加上 $result = mysql_affected_rows();  如果$result 值为-1表明语句没有成功执行,可能是语句格式有问题等等; 如果$result 值为0 表明语句成功执行,但是update并没有改变数据表任何一个字段的值; 如果$result值为1 表明语句成功执行, 而且upda...

九步 628

mysql 无限极递归_mysql8 递归 实现无限极分类

根据id 查询所有的父类或者子类(不包含本类)之前实现无限极分类用的是在代码层实现递归查询,听说mysql8 对递归查询很友好,正好遇到这个功能,就网上搜资料实现了一个简单的功能,确实性能很好,由之前的0.4秒提升到 0.01秒左右实现的效果 : SET FOREIGN_KEY_CHECKS=0;-- ------------------------------ Table structure f...

weixin_29094539的博客 297

mysql select 无限极_查询-mysql无限极分类排序问题

表是这样设计的2,4,5字段请无视现在要查询出来这样格式的数据一级分类二级分类A三级分类A三级分类B二级分类B三级分类A三级分类B我使用的sql为 select * from vn_erp_healthprice order by sortssorts字段为varchar类型查询的结果如下排序结果满足业务要求,但为什么1-11排在1-2前面还有 根据字符串排序这是个什么原理来着 好久没用过这种分...

weixin_29617841的博客 567
上一篇: 遍历目录
下一篇: php字符串切割
wiscourper_
博客等级 码龄17年 1641粉丝 272原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值