Прайс с неизвестным уровнем вложений

DenUs

Новичок
Прайс с неизвестным уровнем вложений

Имеются две таблицы MySQL:

группы прайса
|уровень вложения |ид группы|название|

и собственно таблица с товаром, у каждого товара ссылка на название группы...

В каждой группе имеются подгруппы у которых, в свою очередь, тоже могут быть подгруппы.Ууровень вложений заранее неизвестен. Получается эдакая древовидная структура
Все к чему я пришёл, сводится к множеству запросов к БД типа такого:
PHP:
$query = mysql_query("SELECT * FROM price_group WHERE group_id='0'");
while ($result = mysql_fetch_array($query))
     {
     echo "<tr><td align=center><b>".$result['name']."<b></td></tr>";
     $tov_q = mysql_query("SELECT * FROM price WHERE group_id='".$result['name']."' ");
     while ($tov_r = mysql_fetch_array($tov_q))
          {
          echo "<tr><td bgcolor=#ffffff>".$tov_r['name']."</td>";
          }

     $q1 = mysql_query("SELECT * FROM price_group WHERE group_id='".$result['name']."'");
     while ($r1 = mysql_fetch_array($q1))
          {
          echo "<tr><td colspan=7 bgcolor=#ffffff>".$r1['name']."</td></tr>";
          $tov_q1 = mysql_query("SELECT * FROM price WHERE group_id='".$r1['name']."' AND p1>0");
          while ($tov_r1 = mysql_fetch_array($tov_q1))
               {
               echo "<tr><td bgcolor=#ffffff>".$tov_r1['name']."</td></tr>";
               }
          }
     }
и так далее...
Но поскольку, как я говорил, уровней вложений может быть сколько угодно, код получается громоздкий и неэффективный. Я уже излазил весь форум, но ничего подходящего не нашёл (хотя может не там искал)
Подскажите хотя бы в каком направлении думать.
 

untied

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

Суть метода в том, что каждому узлу присваивается уникальный id (у меня это был m_id -- message identifier) и id родительского сообщения (p_id -- parent identifier).
Для сообщений, стоящих в верху иерархии p_id был равен 0 (то есть родительское сообщение отсутствовало).

Сообщения элементарно сортировались по дате (в соответствии с иерархией) средствами SQL. Древовидная структура при выводе на экран формировалась с помощью стека.
 

SiMM

Новичок
Автор оригинала: untied
Есть гораздо более простой способ хранить древовидные структуры. Этот способ я использовал в движке форума (там была иерархическая струкрура тем обсуждения), и он отлично работал.
На одном-двух уровнях вложенности.
 

SiMM

Новичок
untied, и что же, путь от потомка ты получаешь одним запросом? 80
Это пройденный этап - надо просто внимательнее читать тему топика.
 

untied

Сдвинутый новичок
Originally posted by SiMM
untied, и что же, путь от потомка ты получаешь одним запросом? 80
Это пройденный этап - надо просто внимательнее читать тему топика.
Тема топика: Прайс с неизвестным уровнем вложений
И в теле сообщения автор ничего не пишет по поводу того, что путь от потомка к родителю надо получать одним SQL-запросом.

Цель создания древовидной структуры прайс листа может быть какая угодно. Может ему надо выводить список подгрупп для какой-нибудь выбранной группы товаров? Мой способ легко позволяет это сделать одним запросом. Для других задач -- надо смотреть. Но тоже ничего запредельного. В худшем случае -- стек. :D
 

SiMM

Новичок
Автор оригинала: untied
Тема топика: Прайс с неизвестным уровнем вложений
И в теле сообщения автор ничего не пишет по поводу того, что путь от потомка к родителю надо получать одним SQL-запросом.
Но поскольку, как я говорил, уровней вложений может быть сколько угодно, код получается громоздкий и неэффективный.
 

neko

tеam neko
способ, в данном случае, не является причиной неэффективности
 

SiMM

Новичок
neko, согласен - в код не вдумывался (действительно кривоватый ;) ). Однако предложил, на мой взгляд, более эффективное решение.
 

nw

Новичок
Не знаю как на действительно больших объемах данных, но способ подсказанный untied помоему является одним из классических и изначально не требует большого количества кода (применяется рекурсия).
 

neko

tеam neko
применяется цикл который на больших объемах переносится в субд
 

untied

Сдвинутый новичок
SiMM, я честно прочитал способ, который предлагает рекомендованный Maxim Matyukhin (Хранение древовидных структур в базах данных по методу вложенных множеств (Nested Sets)).

Ну что ж, автор сего способа честно проштудировал теорию графов. Или он помнит институтский курс (да-да, я тоже помню этот курс по МГИЭМу).

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

Но и это еще не вся "шедевральность" метода!

Обычная для веб задача: добавление новой подгруппы в произвольно выбранный узел. (В случае задачи с прайс-листом это происходит довольно часто: появляются новые подгруппы и категории товаров)
В моем способе она решается вот так! (щелкая пальцами)
В методе "Nested Sets" для этого понадобится пересчитать номера входа и выхода для кучи узлов (даже если в самый конец дерева добавлять, все равно придется кучу узлов пересчитывать).

Удаление узла!
Да, в моем способе нужно либо рекурсией либо циклом отследить всех потомков удаляемого узла и удалить их вместе с ним. Но и в методе "Nested Sets" опять же, как и в случае с добавлением, придется пересчитывать кучу узлов.

Перенос подветви в другой узел!
В моем способе просто меняется идентификатор родительского узла. В методе "Nested Sets" (хо-хо!) надо заново пересчитать номера входа, выхода и уровень вложенности.

Сравнения можно продолжать и дальше (например, можно обнаружить, что задача получения всех предков произвольного, взятого с потолка узла в веб-программировании встречается не так часто: обычно движение по страницам происходит от родителей к потомкам -- от групп к подгруппам)
Но, в общем, и так все должно быть понятно. :D
 

SiMM

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