Модераторы: skyboy, MoLeX, Aliance, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Древовидный каталог 
:(
    Опции темы
lancelot555
Дата 7.11.2006, 03:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 19.2.2005

Репутация: нет
Всего: нет



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

      7 0 категория 1 
      8 0 категория 2 
      9 0 категория 3 
      10 7 подкатегория 1 
      11 8 подкатегория 2 
      12 10 подподкатегория 1 
      13 12 555 
      14 9 енгегег 
      16 11 4764тарар 
      17 12 апрапрапр 
      18 12 арарарапрар 
      19 12 1 
      20 12 2 

первая колонка это id
вторая cid
третья имена категорий
cid это индекс той категории которая является категорией на уровень выше данной

вот скрипт который должен выводить все категории и под категории в виде дерева
Код

$q="SELECT * FROM cats where `cid`=0 ORDER BY `name`";
          $res=mysql_query($q);
          global $o;
          $o=1;
          while($row=mysql_fetch_array($res)) {
          echo "<br><strong style=\"color:#333333\">".$row['name']."</strong><br>";
          tree($row['id'],$o);
          }

function tree($cid,$o) {
  $q="SELECT * FROM cats where `cid`='$cid'";
          $res=mysql_query($q);
          $num=mysql_num_rows($res);
          for($j=0;$j<$num;$j++) { $row=mysql_fetch_array($res); 
          for($y=0;$y<$o;$y++) {echo "&nbsp;&nbsp;&nbsp;&nbsp;";}
          echo "{$row['name']}<br />";
          $o++;
          tree($row['id'],$o);
          }          
}


проблема в том что если в какойто категории несколько подкатегорий то $o все равно наращивается на 1 и следующая подкатегория смещается хотя должна находиться на том же уровне.. помогите поправить этот баг..  smile 

p.s. вот так сейчас скрипт выводит дерево:
Код

категория 1
    подкатегория 1
        подподкатегория 1
            555
                апрапрапр
                    арарарапрар
                        1
                            2

категория 2
    подкатегория 2
        4764тарар

категория 3
    енгегег



Это сообщение отредактировал(а) lancelot555 - 7.11.2006, 03:17
--------------------
Hи что так не поpтит цель, как попадание! =)
PM MAIL   Вверх
SelenIT
Дата 7.11.2006, 04:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


баг форума
****


Профиль
Группа: Завсегдатай
Сообщений: 3996
Регистрация: 17.10.2006
Где: Pale Blue Dot

Репутация: 2
Всего: 401



lancelot555, так не подойдет?
Код

function mkTree(&$tree, $cid=0, $level=0){
   foreach($tree[$cid] as $row) {
      echo str_repeat('&nbsp;', $level*4).$row['name']."<br />\n";
      if (isset($tree[$row['id']])) mkTree(&$tree, $row['id'], $level + 1);
   }
}

$tree = array();

$q="SELECT * FROM cats ORDER BY `name`";
$res=mysql_query($q);
while($row=mysql_fetch_assoc($res)) {
   $tree[$row['cid']][] = $row;
}

mkTree($tree);


кажется, первый вариант был с ошибкой - присмотрелся, исправил...

Это сообщение отредактировал(а) SelenIT - 7.11.2006, 22:22


--------------------
Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму!
PM MAIL   Вверх
Eugene_Bond
Дата 7.11.2006, 11:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 138
Регистрация: 3.9.2006

Репутация: 1
Всего: 4



Вот тут самая толковая (ИМХО) из всех статей, посвященных алгоритмике управления Nested Sets
Проще один раз сделать правильный класс для деревьев и пользоваться им, чем нагружать базу и скрипт рекурсивными (или циклическими) переборами.
PM MAIL   Вверх
SelenIT
Дата 7.11.2006, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


баг форума
****


Профиль
Группа: Завсегдатай
Сообщений: 3996
Регистрация: 17.10.2006
Где: Pale Blue Dot

Репутация: 2
Всего: 401



Eugene_Bond, осмелюсь не согласиться, все зависит от задачи. У nested sets свои ограничения, у списков смежности - свои, и в каждом конкретном случае нужно смотреть баланс плюсов и минусов (например, делать перемещение ветви в nested sets в старых версиях mysql, где нет хранимок и транзакций, как-то страшновато). А вот тут Дмитрий Котеров убедительно демонстрирует, что даже многократный self-join в списках смежности (которым так любят пугать новичков) не так уж и страшен...


--------------------
Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму!
PM MAIL   Вверх
Alone
Дата 7.11.2006, 15:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 663
Регистрация: 11.5.2003
Где: Dnepropetrovsk, U A

Репутация: нет
Всего: 6



Я отдаю свой голос в пользу Nested Sets. 
И запросы простые, и избыточности в выводе нет.
Да и просто удобнее пользоваться, даже если придется работать как с черным ящиком.


--------------------
web developer/telecommunication specialist.
mailto: [email protected]
ICQ#28442924

PM MAIL WWW ICQ   Вверх
SelenIT
Дата 7.11.2006, 16:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


баг форума
****


Профиль
Группа: Завсегдатай
Сообщений: 3996
Регистрация: 17.10.2006
Где: Pale Blue Dot

Репутация: 2
Всего: 401



Alone, а какая избыточность в выводе в случае Adjacency List?

Кроме того, есть задачи, которые в чистом Nested Sets в принципе не решаются или решаются с трудом, ценой еще большей избыточности (например, изменение порядка сортировки ветвей или частичное отображение дерева по типу "все разделы первого уровня + подразделы текущего раздела"). Adjacency List в этом плане гибче, т.к. в ней совсем нет избыточности при хранении. А удобство - вещь субъективная, в очень многих случаях Nested Sets - действительно оптимальный компромисс между сложностью организации хранилища и простотой работы с ним. Но, опять же имхо, это далеко не панацея.


--------------------
Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму!
PM MAIL   Вверх
skyboy
Дата 7.11.2006, 16:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 1
Всего: 260



а панацеи не бывает. 
nested sets, как я понимаю, в текущей форме применима только для хранения дерева, но не графа. В отношении каталога это может выглядеть, как, например, попытка отнести цифровые фотоаппараты и в "Фото", и в "Оргтехнику" одновременно. 
надо бы в "Религиозные войны"  smile 
PM MAIL   Вверх
Alone
Дата 7.11.2006, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 663
Регистрация: 11.5.2003
Где: Dnepropetrovsk, U A

Репутация: нет
Всего: 6



skyboy,  Совершенно верно.
Тут уж как говорится кесарю - кесарево, слесарю - слесарево.


SelenIT,  Я имел ввиду тот тестовый кусок, который представлен по ссылке
Меня смутило кол-во возвращаемых столбцов и повторяющееся имя ветки.

Цитата

Кроме того, есть задачи, которые в чистом Nested Sets в принципе не решаются или решаются с трудом, ценой еще большей избыточности (например, изменение порядка сортировки ветвей или частичное отображение дерева по типу "все разделы первого уровня + подразделы текущего раздела")

Гм... А Вы уверены в своих словах? Какая избыточность может наблюдаться при отображении разделов корня + подразделов заданного, если он возвращает _ИМЕННО_ разделы первого уровня + подразделы заданного, и ничего лишнего...

Ну а насчет нерешаемых задач я уже выше высказался, что согласен, панацеи не бывает smile


--------------------
web developer/telecommunication specialist.
mailto: [email protected]
ICQ#28442924

PM MAIL WWW ICQ   Вверх
SelenIT
Дата 7.11.2006, 17:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


баг форума
****


Профиль
Группа: Завсегдатай
Сообщений: 3996
Регистрация: 17.10.2006
Где: Pale Blue Dot

Репутация: 2
Всего: 401



Alone, я имел в виду избыточность не при выводе, а при хранении. Насколько мне известно, даже поле level, используемое в большинстве реализаций nested sets - это уже не часть исходной модели, а ее расширение (избыточность ради удобства).

По ссылке, согласен, выводится немало лишнего - но это ж только демонстрационный пример. Можно ограничить избыточность вывода одними id-ами, а сами данные выбрать, к примеру, еще одним join-ом по условию. А в простейшем выводе всего дерева одним запросом с последующей элементарной (пусть даже рекурсивной) перестановкой ветвей, по-моему, избыточности нет...

skyboy, насчет "религиозных войн" полностью согласен, тема действительно интересная) Мое мнение, даже если ограничиться рассмотрением только деревев (графы пока за кадром): adjacency list хранит именно структуру дерева (связей), а поскольку на практике нужно работать с каким-то представлением этой структуры, для его получения нужны дополнительные действия, зато представление в итоге может быть любым. Nested sets же хранит только одно из возможных представлений дерева (типа проекции структуры на плоскость), и пока потребности ограничиваются этим представлением - все ОК (лучше не бывает), как только выходят за его рамки - так всё...


--------------------
Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму!
PM MAIL   Вверх
IZ@TOP
Дата 7.11.2006, 22:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Панда-бир!
****


Профиль
Группа: Участник
Сообщений: 4795
Регистрация: 3.2.2003
Где: Бамбуковый лес

Репутация: 1
Всего: 73



Предлагаю AJAX'ом строить. Кликаешь по ноде, получаешь ее ID, посылаешь запрос на сервер, там идет поиск наследования и возвращается набор дочерних нод.


--------------------
Один из розовых плюшевых-всадников апокалипсиса... очень злой...

Семь кругов ада для новых элементов языка
Мои разрозненные мысли
PM MAIL WWW ICQ Skype GTalk   Вверх
Eugene_Bond
Дата 8.11.2006, 11:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 138
Регистрация: 3.9.2006

Репутация: 1
Всего: 4



Цитата(SelenIT @  7.11.2006,  14:36 Найти цитируемый пост)
например, делать перемещение ветви в nested sets в старых версиях mysql, где нет хранимок и транзакций, как-то страшновато

абсолютно не страшно. блокировка таблиц была всегда, а запросы (не смотря на кажущуюся громоздкость) быстро срабатывают.

Цитата(SelenIT @  7.11.2006,  14:36 Найти цитируемый пост)
А вот тут Дмитрий Котеров убедительно демонстрирует, что даже многократный self-join в списках смежности (которым так любят пугать новичков) не так уж и страшен... 

1. Не так уже и страшен, но база себя гораздо лучше будет чувствовать если ей дать один простой запрос.
2. На сколько я знаю Дмитрия, у него есть одно замечательное свойство -- он выдумывает идею, находит для реализации оптимальный метод, некоторое время радуется результату и доказывает всем что так лучше чем любым другим способом, потом совершенно забывает об этой идее, а когда в последствии натыкается снова на нее ругается что это просто ерунда какая-то и так делать ни в коем случае нельзя.
Я Дмитрия очень уважаю, но принимать на веру абсолютно все сказанное им нельзя.

Цитата(Alone @  7.11.2006,  15:51 Найти цитируемый пост)
и избыточности в выводе нет.

Цитата(SelenIT @  7.11.2006,  17:29 Найти цитируемый пост)
я имел в виду избыточность не при выводе, а при хранении

Избыточность часто бывает не только вредна, но и полезна

Цитата(SelenIT @  7.11.2006,  17:29 Найти цитируемый пост)
даже поле level, используемое в большинстве реализаций nested sets - это уже не часть исходной модели, а ее расширение (избыточность ради удобства).

Это уж точно удобнее чем циклом генерировать еще один JOIN для среза определенной глубины :-)


Ну, а резюмируя: сам использую как одно представление, так и другое. Иногда микс -- избыточный, но оооочень удобный.
PM MAIL   Вверх
SelenIT
Дата 8.11.2006, 16:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


баг форума
****


Профиль
Группа: Завсегдатай
Сообщений: 3996
Регистрация: 17.10.2006
Где: Pale Blue Dot

Репутация: 2
Всего: 401



Цитата(Eugene_Bond @  8.11.2006,  11:24 Найти цитируемый пост)
некоторое время радуется результату и доказывает всем что так лучше чем любым другим способом, потом совершенно забывает об этой идее, а когда в последствии натыкается снова на нее ругается что это просто ерунда какая-то

...по-моему, так нередко бывает и с "фанатами" nested sets, до и после встречи с  необходимостью пересортировки нод на каждом уровне smile И сказанное ими в первой фазе также не стоит слепо принимать за абсолютную истину.

Цитата(Eugene_Bond @  8.11.2006,  11:24 Найти цитируемый пост)
сам использую как одно представление, так и другое. Иногда микс -- избыточный, но оооочень удобный.

По-моему, вообще оптимальный вариант, особенно для высокой нагрузки.
Некая аналогия с MVC в пределах базы: "модель" - в списках смежности, "view" - в nested sets ;)



--------------------
Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму!
PM MAIL   Вверх
Eugene_Bond
Дата 8.11.2006, 19:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 138
Регистрация: 3.9.2006

Репутация: 1
Всего: 4



Цитата(SelenIT @  8.11.2006,  16:04 Найти цитируемый пост)
Некая аналогия с MVC в пределах базы: "модель" - в списках смежности, "view" - в nested sets ;)

Именно.

Более того, при массовых перетусовках ветвей можно хеш nested tree перестроить "задним числом" как раз по parent id обычного дерева.

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса

Внимание: данный раздел предназначен для решения сложных, нестандартных задач.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Для профи | Следующая тема »


 




[ Время генерации скрипта: 0.0574 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.