Вопрос по mysql – Использование MySQL-запроса для обхода строк для создания рекурсивного дерева

20

У меня есть таблица с перечнем материалов, которая настроена так:
пункт - родитель

Конечный результат при отображении перечня материалов заключается в том, что он отображается следующим образом:

item 1  - parent 0    
    item 2 - parent 1    
    item 3 - parent 1    

Окончательный результат также может быть многоуровневым:

item 3 - parent 0    
    item 4 - parent 3    
    item 76 - parent 3    

И это может продолжаться до бесконечности:

item 76 - parent 0    
    item 46 - parent 76    

item 46 - parent 0     
    item 25 - parent 46

Прямо сейчас я просто получаю 1 уровень из базы данных:

SELECT * FROM bom WHERE parentId = $itemId (shorthand)

Или извлеките каждую строку из таблицы и используйте мою рекурсивную функцию, чтобы отсортировать только те, которые мне нужны, но это, очевидно, неэффективно, поскольку мне может понадобиться только 10 строк, но я извлекаю 10000 записей. Вывод рекурсивной функции просто создаст дерево вроде этого:

item 1
   item 2
   item 3
      item 4
      item 76
         item 46
            item 25

Все, что я знаю, это то, что я начинаю с пункта 1. У пункта 5 может быть родитель 11; они не должны идти последовательно. Я хочу получить все дочерние ветви на дереве. Как я мог сделать этот запрос в MySQL?

Ваш Ответ

4   ответа
7

Вот хороший набор статей об этом:

http://explainextended.com/2009/03/17/hierarchical-queries-in-mysql/

Я знал, что это не основной вопрос. : P Спасибо за статьи. Я обязательно проверю это. phpmeh
36

question in the DBA StackExchange about tree traversal in MySQL, SQL для MySQL не может поддерживать это.

Я написал три (3) хранимых процедуры (GetParentIDByID, GetAncestry and GetFamilyTree) вmy answer to that question, Надеюсь, что эта информация поможет вам построить то, что вы ищете.

Отличная процедура. Но потомSELECT id,GetFamilyTree(id) FROM pctable; выдает ошибку:ERROR 1292 (22007): Truncated incorrect DOUBLE value: '4,5', Я пытался отладить его, но тщетно. Есть ли у вас какие-либо идеи! Спасибо
16

Билл Карвин опубликовал слайд-шоу оиерархические данные в MySQL. Если есть возможность изменить дизайн базы данных, есть несколько других привлекательных способов хранения данных, чтобы упростить запрос. Подходы, которые он охватывает:

  • Adjacency List
  • Path Enumeration
  • Nested Sets
  • Closure Table

На слайде 69 есть хорошая таблица, показывающая плюсы и минусы каждого метода, поэтому я предлагаю вам сначала взглянуть на этот слайд, чтобы увидеть, какой подход может работать для вас, а затем вернуться и посмотреть на детали того, как его реализовать. Обратите внимание, что выбранный вами дизайн (список смежности)only один из четырех представленных проектов, который затрудняет запрос поддерева.

Сказав это, если вы не можете изменить свой дизайн или хотите придерживаться списка смежности, то я должен согласиться с Дидье, что вы должны взглянуть наQuassnoiстатья& quot; Иерархические запросы в MySQL & quot;, Это очень понятная статья, в которой объясняется, как эффективно написать запрос.

Отличный ресурс. Я положил его за вознаграждение, чтобы получить информацию именно так. Спасибо! phpmeh
N ^ 2 один даже считается? Я имею в виду, что таблица станет РАСШИРЕННОЙ в зависимости от вашей структуры данных ... кажется, что левый / правый узел был бы оптимальным выбором, но тогда вам придется беспокоиться об индексации и повторной индексации с помощью вставок строк, верно?
1

Учитывая ваш элемент таблицы (id, parent) и начальный элемент с id = 1, следующее будет работать:

with recursive result(id, parent) as (select id, parent from item where id = 1 union all select i.id, i.parent from item i join result on i.parent = result.id) select * from result;

Похожие вопросы