PHP 移动 mySQL 树节点

发布于 2024-08-25 02:11:33 字数 1112 浏览 3 评论 0原文

我在尝试向上或向下移动子节点或父节点时遇到困难......数学不太好。

如果不存在`pages`则创建表(`page-id`mediumint(8) unsigned

NOT NULL AUTO_INCRMENT,左页 mediumint(8) 无符号 NOT NULL,
page-rightsmallint(8) 无符号 NOT NULL,page-title 文本 NOT NULL,
页面内容文本不为空,
page-time int(11) 无符号 NOT NULL, page-slug 文本不为空,
页面模板文本不为空,
page-parentmediumint(8) 无符号 NOT NULL,页面类型文本NOT NULL, 主键(页面 ID)) 引擎=MyISAM 默认字符集=latin1 ;

插入页面页面id左页右页页面标题页面内容页面时间页面slug页面模板页面父页面类型)值(17, 1, 6, '1', '', 0, '父母', '', 0, ''), (18, 2, 5、'2'、''、0、'SUB'、''、17、'')、 (19, 3, 4, '3', '', 0, 'SUB-SUB', '', 18, ''), (20, 7, 8, '5', '', 0, '测试', '', 0, '');

例如,我如何通过使用左页/右页 ID 将 TEST 移至 PARENT 上方,并将 SUB 移至 SUB-SUB 下方?不需要代码,只需帮助了解 SQL 概念或数学,就能帮助我理解如何更好地移动它......

I am having trouble trying to move sub nodes or parent nodes up or down... not that good at math.

CREATE TABLE IF NOT EXISTS `pages` (   `page-id` mediumint(8) unsigned

NOT NULL AUTO_INCREMENT, page-left
mediumint(8) unsigned NOT NULL,
page-right smallint(8) unsigned NOT
NULL, page-title text NOT NULL,
page-content text NOT NULL,
page-time int(11) unsigned NOT NULL,
page-slug text NOT NULL,
page-template text NOT NULL,
page-parent mediumint(8) unsigned
NOT NULL, page-type text NOT NULL,
PRIMARY KEY (page-id) )
ENGINE=MyISAM DEFAULT CHARSET=latin1
;

INSERT INTO pages (page-id,
page-left, page-right,
page-title, page-content,
page-time, page-slug,
page-template, page-parent,
page-type) VALUES (17, 1, 6, '1',
'', 0, 'PARENT', '', 0, ''), (18, 2,
5, '2', '', 0, 'SUB', '', 17, ''),
(19, 3, 4, '3', '', 0, 'SUB-SUB', '',
18, ''), (20, 7, 8, '5', '', 0,
'TEST', '', 0, '');

As example how would I move TEST up above PARENT and say move SUB down below SUB-SUB by playing with the page-left/page-right IDs? Code is not required just help with the SQL concept or math for it, would help me understand how to move it better...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

千寻… 2024-09-01 02:11:33

所以基本上你想将邻接列表转换为嵌套集?首先更新您的邻接列表(即将 page_parent 值更新为新树的正确值),然后运行下面的转换。

使用 PHP(基本代码,未经测试):

class Tree
{    
    private $count = 0;
    private $data = array();

    /**
     * Rebuild nested set
     * 
     * @param $rawData array Raw tree data
     */
    public function rebuild($rawData)
    {
        $this->data = $rawData;
        $this->count = 1;
        $this->traverse(0);        
    }

    private function traverse($id)
    {
        $lft = $this->count;
        $this->count++;

        if (isset($this->data[$id])) {
            $kid = $this->data[$id];
            if ($kid) {
                foreach ($kid as $c) {
                    $this->traverse($c);
                }
            }
        }

        $rgt = $this->count;
        $this->count++;

        // TODO: Update left and right values to $lft & $rgt in your DB for page_id $id
        ...
    }
}

当您调用它时,$rawData应该包含一个ID数组,由parent-id索引,您可以创建它(基于您的表结构)如下($db应该包含一个活动的PDO连接对象):

    $sql = 'SELECT page_id, page_parent FROM pages ORDER BY page_parent';

    $stmt = $db->prepare($sql);
    $rawData = array();
    $stmt->execute();
    while ($row = $stmt->fetch()) {
        $parent = $row['page_parent'];
        $child = $row['page_id'];
        if (!array_key_exists($parent, $rawData)) {
            $rawData[$parent] = array();
        }
        $rawData[$parent][] = $child;
    }

要进行转换,您需要类似的东西:

$tree = new Tree();
$tree->rebuild($rawData);

所以基本上你创建一个数组,其中包含树中由父索引索引的所有节点,该数组将以递归方式遍历以确定每个节点的正确左值和右值。

顺便说一句,你可以用普通的 SQL 来完成它(在调整表/列名称之后):
http://bytes.com/topic/ mysql/answers/638123-regenerate-nested-set-using-parent_id-struct

So basically you want to convert an adjacency list to a nested set? First update your adjacency list (ie. update the page_parent values to the correct values for your new tree), then run the conversion below.

Using PHP (basic code, untested) :

class Tree
{    
    private $count = 0;
    private $data = array();

    /**
     * Rebuild nested set
     * 
     * @param $rawData array Raw tree data
     */
    public function rebuild($rawData)
    {
        $this->data = $rawData;
        $this->count = 1;
        $this->traverse(0);        
    }

    private function traverse($id)
    {
        $lft = $this->count;
        $this->count++;

        if (isset($this->data[$id])) {
            $kid = $this->data[$id];
            if ($kid) {
                foreach ($kid as $c) {
                    $this->traverse($c);
                }
            }
        }

        $rgt = $this->count;
        $this->count++;

        // TODO: Update left and right values to $lft & $rgt in your DB for page_id $id
        ...
    }
}

When you call this, $rawData should contain an array of ID's, indexed by parent-id, you could create it (based on your table structure) as follows ($db should contain an active PDO connection object):

    $sql = 'SELECT page_id, page_parent FROM pages ORDER BY page_parent';

    $stmt = $db->prepare($sql);
    $rawData = array();
    $stmt->execute();
    while ($row = $stmt->fetch()) {
        $parent = $row['page_parent'];
        $child = $row['page_id'];
        if (!array_key_exists($parent, $rawData)) {
            $rawData[$parent] = array();
        }
        $rawData[$parent][] = $child;
    }

To do the conversion you would need something like :

$tree = new Tree();
$tree->rebuild($rawData);

So basically you create an array that is containing all nodes in your tree indexed by parent which will be traversed in a recursive manner to determine the correct left and right values per node.

BTW You could do it in plain SQL (after you adapt table/column names) :
http://bytes.com/topic/mysql/answers/638123-regenerate-nested-set-using-parent_id-structure

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文