开发者

PHP Moving mySQL Tree Node

开发者 https://www.devze.com 2022-12-22 22:27 出处:网络
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

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, 开发者_JAVA百科''), (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...


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

0

精彩评论

暂无评论...
验证码 换一张
取 消