PHP: сортировка данных из вложенных наборов - PullRequest
1 голос
/ 16 мая 2009

В настоящее время мы создаем веб-сайт с категоризованной таблицей MySQL, содержащей различные компетенции, и мы заметили, что модель для вложенного набора будет оптимизирована для этого. Хотя у нас есть довольно серьезная проблема - модель с вложенными множествами не допускает сортировки, и нам действительно нужна такая возможность. Я хотел бы, чтобы выходные данные были массивом (идентификатор, имя, глубина) , поскольку эта функция поддерживает (хотя и без какой-либо сортировки):

function tree()
{
    $query = 'SELECT node.id, node.name, (COUNT(parent.name) - 1) AS depth FROM test_competence AS node, test_competence AS parent WHERE node.lft BETWEEN parent.lft AND parent.rgt GROUP BY node.name ORDER BY node.lft';
    $result = mysql_query($query) or die(mysql_error());

    while($data = mysql_fetch_assoc($result))
    {
        $returnarray[] = $data;
    }

    return $returnarray;
}

Я начал с функции, но не знаю, как продолжить:

function tree_sorted()
{
    //Get data
    $query = 'SELECT node.id, node.name, node.parent, (COUNT(parent.name) - 1) AS depth FROM test_competence AS node, test_competence AS parent WHERE node.lft BETWEEN parent.lft AND parent.rgt GROUP BY node.name ORDER BY node.lft';
    $result = mysql_query($query) or die(mysql_error());

    //Fetch gotten data
    while($data = mysql_fetch_assoc($result))
    {
        $fetched[$data['depth']][$data['id']] = array($data['name'], $data['parent']);
    }

    //Sort fetched data
    foreach($fetched as $i => $row)
    {
        asort($row);
        $sorted[$i] = $row;
    }

    //Merge sorted data (???)
    foreach($sorted as $i => $arr)
    {
        foreach($arr as $x => $row)
        {
            $returnarray[] = array('id' => key($row), 'name' => $row[0], 'depth' => $x);
        }
    }

Любая помощь будет принята с благодарностью. Я гуглил разные способы сортировки данных из вложенных множеств, но без какого-либо хорошего результата.

Заранее спасибо.

РЕДАКТИРОВАТЬ : Сейчас я попробовал некоторые с функцией uasort (), которая кажется правильным, но проблема все еще остается.

Ответы [ 3 ]

1 голос
/ 02 июня 2009

Если вам нужно отсортировать набор узлов в дереве и поддерживать неограниченное количество уровней в дереве, могу ли я рекомендовать использовать предварительно упорядоченный обход дерева?

См. http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/ для примера реализации.

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

Единственным заметным недостатком этого подхода является то, что вам нужно активно поддерживать эти левые и правые значения при изменении структуры узлов.

0 голосов
/ 18 мая 2009

Делая удар в темноте, поскольку вложенные данные дерева наборов по определению уже отсортированы, похоже, что вам нужно преобразовать данные в другой формат (обычно плоский), чтобы отсортировать их. Самый простой способ добиться этого - просто работать с данными, создавая плоский набор данных на ходу.

У вас уже есть несколько опций в SQL. Упорядочение по левому идентификатору поможет вам в обратном порядке, если я правильно понял терминологию. Это обычно то, что люди хотят, когда они перечисляют дерево множеств, поскольку это имеет смысл, когда сплющено в список. Я бы экспериментировал с предложением ORDER BY в SQL; например, упорядочение по параметру глубины даст вам обход уровня порядка. Попробуйте объединить это с node.name.

0 голосов
/ 16 мая 2009

По моему опыту, использование модели с вложенным множеством не является действительно необходимым, если вы не ожидаете некоторого действительно интенсивного трафика. Я не уверен, для чего именно вам нужна иерархия, но я бы порекомендовал проверить, не будет ли достаточной простая таблица parent-son-table с кэшем перед ней, ее намного проще поддерживать и работать с

Опять же, это, конечно, зависит от вашего приложения и того, насколько вы обеспокоены проблемами с производительностью.

...