Хранение меню и подменю. Подскажите идею.

Mark&Ameli

Новичок
Хранение меню и подменю. Подскажите идею.

Вот сталкнулся с такой проблемой:
нужно создать редактируемое меню с подменю. Вот незнаю как. Все никак не могу придумать как хранить меню и подменю. Тоесть пользователь создает меню, оно создается. Создает подменю в этом меню, оно создается. Все это хранится в бд. И тут возникае вопрос: как выводить это все из бд? Тоесть как различать меню и подменю. Как вывести (и соответственнно, как их заносить в бд) это все из бд? Как объяснить интерпритатору, что это именно меню, а это именно подменю, и относится оно именно к этому меню...

Вот, подскажите кто-нибудь идею... Третий день маюсь :(
 

Mark&Ameli

Новичок
magic
А там усё не по-русски :(

zerkms
Интересная ссылка... Щас покапаюсь, может чего-то и найду. Спасибо.
 

maxru

МИФИст
Я делал Виртуальную систему шаблонов, может она пригодится для менюшек.
TABLE filesystem
int fid
text filename
text parent
text template
int permissions

Значит в строке браузера что-то типа: http://www.vasyapupkin.ru/?path=archive/news/byvasya&date=05072004

В БАЗЕ:
fid filename parent template permissions
1 archive NULL dirlist.tpl 1
2 news 1 newslist.tpl 1
3 byvasya 2 newslist.tpl 1

Выборка
SELECT fid,template FROM filesystem WHERE filename='archive' AND parent is NULL
Получаем fid
SELECT fid,template FROM filesystem WHERE filename='news' AND parent=$fid

и так далее до победного.
Может быть что-то рассказал не так, что-то забыл, но мысль вроде ясна.
 

Royal Flash

-=MaestrO=-
Mark&Ameli
nested sets - для меню сайта - не самый лучший вариант, а особенно, разобраться в этом новичку...

Начни с базы вида id parent_id(id родителя).
Т.е. в базу заносится для каждого пункта меню и подменю (не имеет значения) id, id родителя, название меню, другая инфо
Например дерево, вида
1меню
1подменю
1подменюподменю
2подменю
2меню
3меню

В базе будет иметь вид:
id name ........................ parent_id
1 меню ........................ 0
2 1подменю................. 1
3 1подменюподменю.. 2
4 2подменю................. 1
5 2меню....................... 0
6 3меню....................... 0

Как этим пользоваться:
http://dbtree.dklab.ru/search.php?mask=/&depth=4&num=100&count=on
 

Mark&Ameli

Новичок
Royal Flash
Да, я к такому решения сам уже пришел. 5 дней мучался...думал...так ничего и не придумал :(
Потом глянул как все это дело хранит в базе ShopScriptFree, и все встало на свои места. Хотя я уже начал подозревать, что так и надо...
Потом возникли небольшие (сроком в 12 часов) проблемки с выводом из базы, но с ними я уже справился. Правда незнаю правильным ли способом (какой-то странный он получился), но тем не менее усё работае, а это главное.

Всем спасибо... :)
 

Wicked

Новичок
Автор оригинала: Royal Flash
nested sets - для меню сайта - не самый лучший вариант, а особенно, разобраться в этом новичку...
Имхо нестед сетс все таки получше будут. По крайней мере, класс для работы с нестед сетс позволяет свое дерево легко модифицировать. А структура хранения записей - делать всякие замысловатые выборки в 1-2 запроса (а не в кол-ве, зависящем от кол-ва уровней или вообще всех элементов).

Что же насчет "разобраться" - достаточно прочитать ту небольшую статью.
 

Royal Flash

-=MaestrO=-
Wicked
делать всякие замысловатые выборки в 1-2 запроса (а не в кол-ве, зависящем от кол-ва уровней или вообще всех элементов).
Если вы посмотрите ссылку, приведенную мной высше, то увидете, что выборка любого кол-ва уровней (до 61 - ограничение на кол-во объеденений для MySQL 4.1) производится всего в 1 SQL запрос. Для меню сайта, это есть самый лучший вариант.
 

Wicked

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

Wicked

Новичок
Потому что эти выборки - из разряда хранения динамического количества полей в широких таблицах id, field1, field2, ..., fieldN.

-~{}~ 22.05.06 18:36:

Т.е., применительно к dbtee.dklab.ru: он не позволяет единообразно работать с элементами различного уровня. И совсем не позволяет работать с элементами глубже некоторого наперед заданного уровня.
 

baev

‹°°¬•
Команда форума
Потому что эти выборки - из разряда хранения динамического количества полей в широких таблицах id, field1, field2, ..., fieldN.
Честно говоря, не вижу ничего общего.
Может, мы об разном?

(Вообще, обоснование вышеописанного способа тут:
http://forum.dklab.ru/viewtopic.php?p=71055#71055 )
 

Wicked

Новичок
baev
Да, я именно об этом.

Честно говоря, не вижу ничего общего.
да чего стоит только заголовок того result set'а (оформленного в виде хтмл таблицы):
0.id, 0.text, 1.text, 2.text, ... N.text

Совсем не похоже на: id, field1, field2, ..., fieldN ?

Естественно, что этот выбор - дело сугубо субъективное. Я приверженец nested sets. И со своей любовью к внутренней красоте программ - не вижу альтернатив.
 

Royal Flash

-=MaestrO=-
Wicked
Плюсы таблиц с id --> parent id по сравнению с nested sets:
+ скорость добавления записи (особенно при большом кол-ве записей)
+ ничем не уступающая скорость чтения при кол-ве записей до 2000 (приблизительно), хотя еще сильно зависит от дополнительных колонок таблицы...
+ более устойчива к краху (в случае глюка базы во время выполнения опирации вставки)

-~{}~ 23.05.06 03:10:

Wicked
Да, и еще, хотелось бы узнать, на сколько сложно (или легко) можно запустить сортировку в таблице nested sets, например по дополнительной колонке "порядковый номер записи", и изменить этот "порядковый номер записи" в случае необходимости?

-~{}~ 23.05.06 03:13:

Единственный минус, в id --> parent вижу пока только один - в случае добавления прав доступа, эти права приходится менять всем детям родителя, в nested sets, по моему, возможно присвоить только родителю, детям менять не нужно?
 

Гриша К.

Новичок
Вот тема сообщения: http://phpclub.ru/talk/showthread.php?s=&threadid=85665&rand=0, там же есть ссылка на пример меню с подменю (с неограниченным уровнем вложенности) и с исходным кодом, метод хранения в БД - списки смежности. Для 2-х уровнего меню очень даже подойдет и заодно запас есть. И метод хранения позже легко можно поменять на другой.
Попозже я там также размещу скрипт для управления этим меню.

Вам уже оставляли ссылку: http://phpclub.ru/faq/wakka.php?wakka=YuriPopoff&v=y3u (раздел древовидное меню), посмотрите еще раз может и сами разберетесь, там очень много полезной информации и готовых примеров.
 

maxru

МИФИст
В моём примере тоже неограниченный размер вложенности.
Сам признаю, что очевидный минус - это количество запросов к БД (и связанное с этим увеличение времени генерации контента). Однако, 5-6 запросов к БД выполнятся ОЧЕНЬ быстро, и я не думаю, что кто-то будет создавать 1457-уровневое меню.

Кстати элементы с parent=NULL это корневые элементы.
Поэтому первый запрос будет отличаться от остальных, которые, кстати, можно будет генерировать.

Nested Sets, по-моему, неприменимы для генерации меню - это тоже самое, что бульдозером кусты подстригать.
А вот для генерации моей Filesystem может подойдут.
Если сравню производительность, то создам топик с результатами.

-~{}~ 26.05.06 13:32:

Скажем, мне, чтобы вытащить один шаблон необходимо выполнить 3 запроса (для вышеописанного примера).
Пусть человек имеет трёхуровневое меню (если уровней больше, то юзер обычно уходит с сайта, будучи не в силах переварить такую сложную структуру 8) ) и элементов в главном меню 10 и каждый имеет подменю из 3х элементов, в каждом подподменю из 3х элементов. Давайте посчитаем количество запросов.

1) Запрашиваем список корневых элементов. +1
2) Запрашиваем для корневых элементов по списку подэлементов +10
3) Запрашиваем для подэлементов списки подподэлементов
+30
Итого 41 запрос.

Некоторые уже догадались, что этот подсчёт верен только для случая полностью открытого списка. Где вы видели безумца, у которого на сайте полностью открытый список из 10*3*3=90 элементов? Вполне логично, что в один момент времени открыто :
а) 10 главных элементов (+1 запрос)
б) 3 подэлемента (+1 запрос)
в) 3 подподэлемента (+1 запрос)

Итого 3!!! запроса к базе данных.

-~{}~ 26.05.06 13:35:

Дополнение:

Если вы создаёте dhtml меню, типа как в http://www.ultra-online.ru, то вам действительно придётся сгенерировать 41 запрос.
 
Сверху