PHP Перемещение MySQL Tree Node - PullRequest
       6

PHP Перемещение MySQL Tree Node

0 голосов
/ 12 марта 2010

У меня проблемы с попыткой переместить подузлы или родительские узлы вверх или вниз ... не очень хорошо в математике.

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

NOT NULL AUTO_INCREMENT, page-left mediumint (8) без знака NOT NULL,
page-right smallint (8) без знака НЕ NULL, page-title текст НЕ NULL,
page-content текст НЕ НУЛЬ,
page-time int (11) без знака NOT NULL, page-slug текст НЕ НУЛЬ,
page-template текст НЕ НУЛЬ,
page-parent mediumint (8) без знака NOT NULL, page-type текст NOT NULL, ПЕРВИЧНЫЙ КЛЮЧ (page-id)) ДВИГАТЕЛЬ = CHISSET ПО УМОЛЧАНИЮ MyISAM = latin1 ;

INSERT INTO pages (page-id, page-left, page-right, page-title, page-content, page-time, page-slug, page-template, page-parent, page-type) ЗНАЧЕНИЯ (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, 'ТЕСТ', '', 0, '');

Как пример, как бы я переместил TEST выше PARENT и сказал бы переместить SUB ниже SUB-SUB, играя с идентификаторами page-left / page-right? Код не требуется просто помочь с концепцией SQL или математики для него, помог бы мне понять, как лучше его переместить ...

1 Ответ

3 голосов
/ 12 марта 2010

Итак, вы хотите преобразовать список смежности во вложенный набор? Сначала обновите список смежности (т. Е. Обновите значения 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 должен содержать массив идентификаторов, проиндексированных по 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-structure

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...