| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > PHP: Общие вопросы > Вывод дерева из БД |
| Автор: mark2011 28.7.2011, 16:52 | ||||
| Избитая, конечно, тема, ну да ладно.... В прикреплённом файлике структура таблицы. Задача проста - вывести её на экран. Делаю так:
Так, занесли в переменную корень дерева... Хорошо, идём дальше...
Логично, правда? Посмотрите на рисунок: у корня cat_id=29, он же parent_id у второго элемента. Казалось бы, повторяй эту конструкцию в цикле, ан нет... У элемента "1.1.1" cat_id=31, но не существует элемента, у которого parent_id=31. Значит автоматически указанное выше условие рекурсии недействительно. Из этого совершенно непонятно условие выхода из рекурсии... если честно, я даже его словами не могу сформулировать... Знаю, что существуют обходы деревьев (префиксный, постфиксный и инфиксный) но, насколько я знаю, это для деревьев Nested Sets, там где используется left_id, right_id... А у меня очень простая структура. В общем то надо условие повтора (ради чего рекурсия) и условие выхода из рекурсии... Всем откликнувшимся огромное спасибо |
| Автор: Sanchezzz 31.7.2011, 03:47 | ||
что то типо того должно быть я так понимаю ?
parent_id должен быть в таблицы по дефолту стоять 0 по умолчанию если он не является потомком. |
| Автор: mark2011 2.8.2011, 09:33 |
| Sanchezzz, Такой вариант не работает однозначно, я проверил. Но вот о чём я задумался.... в принципе дерево можно всё за один проход передать в массив и дальше уже работать с этим массивом. С другой стороны, дерево может быть очень большое и массив может получиться огромный. Вот.... возникает вопрос, где будет больше накладных расходов - при прохождении массивом, или прямым рекурсивным выводом из базы? |
| Автор: baldina 2.8.2011, 10:15 | ||
нельзя сказать однозначно. зависит от размера данных, нагрузки на базу, нагрузки на сервер php. по возможности всю работу целесообразно переложить на СУБД, выполняя иерархический запрос. Напрямую иерархические запросы могут не поддерживаться, это потребует программирования на стороне СУБД |
| Автор: нуп 2.8.2011, 10:40 |
| Да тупо кэшировать категории и всё |
| Автор: CruorVult 2.8.2011, 10:52 | ||
А зачем вытаскивать всё дерево ? Если оно очень большое - юзеру думаю не в кайф будет листать всё. Обычно вытягивается верхний уровень и потом аяксом вытягивается нужные подкатегории. |
| Автор: mark2011 2.8.2011, 11:41 |
| CruorVult, В некоторых случаях - да. Но у меня была ситуация, когда потребовалось тянуть всё дерево, аякс работал, но был неприемлем для заказчика. baldina, Ну по вашей логике: существует элемент с cat_id = 32, но не существует элемента parent_id = 32. Этот элемент лист - конец рекурсии. А элемент с cat_id = 33? Получается что он вообще не войдёт в выборку? |
| Автор: CruorVult 2.8.2011, 12:20 | ||
с какого перепуга? Судя с дампа на рисунке cat_id = 33 он не имеет ни малейшего отношения к 32. Да и вообще, вопрос по-моему уже ришен, просто вы никак не хотите начать думать |
| Автор: gcc 2.8.2011, 12:24 |
| если таблица с одним деревом не 100гиг, то можно использовать http://www.google.com.ua/#hl=ru&source=hp&q=Nested+Set+&oq=Nested+Set+&aq=f&aqi=g10&aql=&gs_sm=e&gs_upl=629l629l0l1056l1l1l0l0l0l0l274l274l2-1l1l0&fp=258deabd11a5a999&biw=1280&bih=799 и еще примеры есть с innodb |
| Автор: baldina 2.8.2011, 12:45 | ||||
да
это от вас зависит, как вы хотите. или не войдет, или будет на верхнем уровне (как будто его parent_id=0) вообще-то я все это уже говорил. и пример вам сделал, работающий с вашими данными Добавлено через 57 секунд http://codepad.org/dPYKaHtG смотрели? Добавлено через 6 минут и 33 секунды и вот это http://codepad.org/HwoD1QWJ |
| Автор: mark2011 19.10.2011, 13:22 | ||||
| Ну что ж, заново открываю мной же созданную тему... Итак, структура базы данных та же. Вариант, предложенный Sanchezzz, после допиливания работает, но выдаёт следующее:
Т.е. как бы нормально, НО: Почему-то уровень всё время первый, т.е. невозможно однозначно отследить где начинается потомок. Вот мой допиленный код:
|
| Автор: MoLeX 19.10.2011, 19:35 |
| http://habrahabr.ru/tag/nested%20set/ http://www.google.ru/#sclient=psy-ab&hl=ru&newwindow=1&source=hp&q=nested%20sets&pbx=1&oq=neste&aq=1&aqi=g4&aql=1&gs_sm=sc&gs_upl=1070l6269l0l10145l8l7l1l0l0l0l1166l2887l2-3.3.7-1l8l0&bav=on.2,or.r_gc.r_pw.,cf.osb&fp=722f8ceee399dfd&biw=1920&bih=890&pf=p&pdl=300 |
| Автор: mark2011 20.10.2011, 08:14 |
| Я не могу использовать вложенные множества. Во-первых это потребует изменения структуры таблицы, во вторых у меня не такое разветвлённое дерево. Изменять структуру таблицы не нужно. |
| Автор: MoLeX 20.10.2011, 08:32 |
| mark2011, плодите тогда запросы к СУБД. Это ваше право, наше дело предложить |
| Автор: mark2011 20.10.2011, 08:46 | ||||||
Я уже мало что понимаю.... накопал следующую функцию:
Использую её следующим образом:
В ответ получаю:
Т.е. в выводе пропущены элементы. Кто-нибудь подскажет вообще в чём причина? |
| Автор: MoLeX 20.10.2011, 13:05 | ||
|
| Автор: patap 20.10.2011, 13:15 |
| вот посмотри http://kod34fr33.wordpress.com/2008/05/06/adjacency-list-tree-on-mysql/ |