MPTT (модифицированный обход дерева предзаказа) в PHP - PullRequest
2 голосов
/ 28 октября 2009

Мой первый пост здесь! Похоже, что это место, чтобы стать мудрым;)

В настоящее время я нахожусь в середине некоторого тестирования с моей первой попыткой попробовать подход MPTT (Modified Preorder Tree Traversal) для хранения данных в моей базе данных MySQL с помощью PHP.

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

Это может привести к получению категорий Saab и Chrysler из рисунка ниже, если введенный родитель будет называться «Bilar». (Что означает «Автомобили» по-шведски, если это не ваша сильная сторона;))

Поскольку я не могу публиковать изображения, вот ссылка на блок-схему: http://www.phpsidan.nu/files/mptt/mptt1.png

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

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

Большое спасибо!

Ответы [ 2 ]

1 голос
/ 07 февраля 2010

Я уверен, что это можно было бы оптимизировать, однако, если у вас есть столбцы «name», «lft» и «rgt», следующее даст вам братьев 2-го уровня «Bilar».

SELECT node.name,                                                                                                                                     
       node.lft AS sort,                                                                                                                                                                                                                                                               
       (COUNT(parent.name) - (sub_tree.depth + 1)) AS depth                                                                        

FROM car AS node,                                                                                                                                  
     car AS parent,                                                                                                                                
             car AS sub_parent,                                                                                                                            
             ( SELECT node.name, (COUNT(parent.name) - 1) AS depth                                                                                          
                 FROM car AS node,                                                                                                                         
                      car AS parent                                                                                                                        
                WHERE node.lft BETWEEN parent.lft AND parent.rgt                                                                                            
                  AND node.name = "Bilar"                                                                                                                       
             GROUP BY node.name                                                                                                                             
             ORDER BY node.lft) AS sub_tree

WHERE node.lft BETWEEN parent.lft AND parent.rgt                                                                                                     
  AND node.lft BETWEEN sub_parent.lft AND sub_parent.rgt                                                                                             
  AND sub_parent.name = sub_tree.name

GROUP BY node.name HAVING depth <= 2                                                                                                                 
ORDER BY node.lft
0 голосов
/ 28 октября 2009

http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/ содержит информацию и примеры запросов для вложенных множеств

получить непосредственных детей в NS сложно, поэтому некоторые люди предпочитают хранить явный parent_id вместе с указателями «left» и «right».

...