Запрос с Рекурсией

Falc

Новичок
гоша
>>А так -- много запросов делать, в цикле.
Ну не так уж и много всего N запросов, где n глубина дерева.

>>Если таблица у тебя маленькая, то дешевле ее одним запросом засосать в память и обходить деревом уже пыхом.

Засасывать всю таблицу в пых чтобы получить путь, это глупо.
 

doctor Ruust

Guest
Автор оригинала: Falc
doctor Ruust
>>В PHP5 с MySQL4.1 ты его один раз откомпилишь (mysqli_prepare, кажется), а потом несколько раз будешь использовать.
Про это неслышал, да и ПХП 5 еще нету.

С обычной рекурсией в ПХП тоже никакиз JOINов, и на 2 запроса меньше.
А как ты борешься с петлями в рекурсии, массив создаёшь?
Вот работающий пример:
PHP:
/*
	 create table T ( id int, pid int );
	 insert T values (1,0),(2,1),(3,2),(4,3),(5,4),(6,6); 
*/
mysql_query('select @set:="", @id:=4');
$sql = '
	 select @set := if(@set = "", id, concat(@set, ",", id)), (@id := pid) as pid, id
	 from T
	 where not find_in_set(@id, @set) and id = @id';
while($row = mysql_fetch_array(mysql_query($sql))) { 
	echo $row['id'] . '<br>';
}
 

Falc

Новичок
doctor Ruust
>>А как ты борешься с петлями в рекурсии, массив создаёшь?
Я с ними не борюсь, дерево не может иметь петли, иначе это будет уже не дерево, а сеть или как там еще называется.
 

гоша

Guest
Falc

запрос надо 1) построить 2) отправить мускулю 3) прочитать ответ. Сравни это с одной ссылкой по памяти в пыхе...

Но я и не говорю, что это хороший вариант.
Правильнее всего -- дерево нормально организовать.
 

Falc

Новичок
гоша
Т.е. ты читаешь такую организацию не нормальной?
Обоснуй.
 

гоша

Guest
нормальной считаю такую организацию дерева, при которой, например:

Можно вывести всю цепочку от текущего элемента до верхнего одним SQL запросом

нестед сетс, path model (то что доктор предлагает), dom-xml и так далее.
 

Falc

Новичок
гоша
Т.е. о нормальности ты судешь только по одному критерию
"Можно вывести всю цепочку от текущего элемента до верхнего одним SQL запросом"

Похоже твоя работа с деревьями ограничивается только выводом цепочек.

И не понятно чем тебя пугают несколько запросов вместо одного.
 

Falc

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

martinelli

Новичок
Всем спасибо. забавно что тема вернулась.
Я еще в начале декабря все реализовал.
Уровень вложенности не превышает 2, так что вполне хватило двух left join.
вот текст, если кому-нибудь это будет интересно

PHP:
//возвращает полную информацию о теме, включая есть ли у нее файлы, подтемы и названия тем верхнего уровня(при их наличии)
sql_query="select themes.cat_id, themes.cat_name, themes.cat_nameeng, themes.cat_level, themes.cat_cid,
  th1.cat_id as th1_id, th1.cat_name as th1_name, th1.cat_nameeng as th1_nameeng,
  th2.cat_id as th2_id, th2.cat_name as th2_name, th2.cat_nameeng as th2_nameeng,
  count(fl_cid) as count_files, count(th0.cat_cid) as count_podtheme
  from (((themes left join themes as th1 on themes.cat_cid = th1.cat_id)
  left join themes as th2 on th1.cat_cid = th2.cat_id) left join files on themes.cat_id = fl_cid) 
  left join themes as th0 on themes.cat_id = th0.cat_cid
  where  themes.cat_id=$id group by themes.cat_id";
 

clevel

Новичок
хм, а я для себя создал дополнительное поле - pids, в котором через запятую храню все id родителей...
При необходимости можно вытащить это поле и просто одним запросом достать всех родителей со всеми характеристиками...
 

Falc

Новичок
clevel
Можно, только переностить ветку будет не очень приятно.
 

гоша

Guest
Переносить-то как раз нормально (одним опять-таки запросом). Самый большой недостаток path модели -- ограничения на ширину и глубину дерева.

Falc
> чем тебя пугают несколько запросов вместо одного.

Меня лично мало что пугает. Я просто хотел указать, что для хранения древовидных структур в РСУБД (или в мускуле конкретно) разработаны более эффективные способы, чем примененный автором темы.
 

Falc

Новичок
гоша
>>разработаны более эффективные способы, чем примененный автором темы.
Не стоит говорить об эфективности того или иного метода в общем. Я могу привести ситуацию когда метод id|parent_id будет более ефективен, например, когда апдейтов и инсертов в дереве больше нежели выборок.
 

Линк

Guest
лично я использую метод, описанный в статье "деревья в SQL" (рыскать на яндексе) позволяющий хранить сколь угодно длинные деревья в двумерном SQL))

правда есть узкие места: Удаление и добавление происходит в пару-тройку запросов

зато вывод всех родителей и всех детей черезвычайно быстр
 

KES

Guest
нормальной считаю такую организацию дерева, при которой, например:

Можно вывести всю цепочку от текущего элемента до верхнего одним SQL запросом
Спорить об эффективности бессмысленно - нужно исходить от поставленной цели и исходных данных.
Целиком согласен с Falc

Можно и так.

mysql_query('select @prev:=0');
$sql = 'select (@prev := id) as id, cid from table where cid = @prev';
while($row = mysql_fetch_array(mysql_query($sql))) {
}
Вот тебе идея. Вот ее и юзай ее, а не собирай исходники по разным форумам и делай из них "что-то".
 

Линк

Guest
while($row = mysql_fetch_array(mysql_query($sql)))
Дополняя сказанное. Данная конструкция все же будет очень долго работать (в большинстве случаев) так что лучше (imho) делать
http://sdm.viptop.ru/articles/sqltrees.html
ибо там можно получить всех детей или всех родителей всего ОДНИМ запросом.

Но все зависит от задач, как сказали тут...
 

Falc

Новичок
Линк
>>Данная конструкция все же будет очень долго работать

Ты много в веб задачах видел деревьев в которых подобная конструкция будут долго работать?
 

Линк

Guest
Честно сказать?
только одну)))):D там было по 20-30 уровеней иерархии)
 

Falc

Новичок
Линк
Я тоже только одну :)
Уровней там правда неограничено было, но реально 10-200, причем выводить все 200 не приходилось.
 

Линк

Guest
в моей тоже не ограничено
а реально 20-30

в том то и фишка моего метода, что там уровней НЕОГРАНИЧЕНО, а запрос всего один
 
Сверху