Частенько возникает необходимость организовать что-либо в виде дерева, например форум. Первое, что приходит в голову, это создать таблицу с примерно такой структурой: Код (Text): id - номер сообщения parent_id - номер сообщения родителя (0, если сообщение начало темы) body - собственно, сообщение Но чтобы вывести такой форум придется использовать рекурсию, что очень дурно повлияет на производительность скрипта. Поэтому, у меня появилась идея: использовать специальное поле для сортировки строк. Итак, подробнее. Сначала создадим таблицу 'msgs' такого содержания: Код (Text): body - само сообщение orderby - то самое специальное поле Итак, в этом поле будут храниться даты сообщений в формате: Код (Text): дата сообщения, которое является началом темы / дата ответа на это предыдущее сообщение / дата ответа на это предыдущее сообщение ... Если пользователь начинает новую тему например 1 января 2007 года в 00:00, то это поле имеет такой вид: Код (Text): 2007-01-01 00:00 Позже пришел еще какой-то пользователь и решил написать свое сообщение (в час ночи), тогда поле имеет такой вид: Код (Text): 2007-01-01 00:00/2007-01-01 01:00 И так далее, по нарастающей. Теперь чтобы выбрать нужные строки и в нужном порядке то надо будет использовать всего 1 запрос, не используя рекурсию: [sql]SELECT * FROM msgs ORDER BY orderby ASC[/sql] Все стало намного прозрачнее, НО есть один минус длина поля будет постоянно расти, поэтому придется позаботится о том, чтобы длина поля была достаточной или использовать другой формат записи например не использовать дату а unix timestamp.
Vitas Можно вопрос: а почему у тебя форум получился в виде дерева? Все современные профессиональные движки (SMF, vB, IPB, phpBB) - не древовидные, а нитевидные. Наверное, неспроста их создатели так решили. Древовидной может быть структура разделов, но не сообщения. Иначе форум быстро превратится в помойку, в которой фиг чего найдешь (имхо).
Алгоритмы сортировки занимают больше времени,чем выборка необходимых элементов при правильном построении дерева.Думаю что самый быстрый вариант для реализации этой мысли будет использовать какое-нибудь self-balancing heap-ообразное дерево и выводить затем данные "in level-order".Т.е. сортировка будет производиться лишь 1 раз при добавлении новых постов/ответов,а не каждый раз,как в приведённом тобой примере.Значения элементов = время поста + дополнительные указатели в каждом из элементов на остальную инфу. Для каждого поста новое дерево,каждый элемент которого будет ссылаться на поддерево "ответов к посту".Правда писать такое думаю придёться на С,если нет уже готовых реализаций в существующих базах данных
Vitas Хм... в таком случае тебя понесло не в ту степь, имхо. Если ты вместо форума будешь рассматривать другую предметную область, то у тебя все изменится - исчезнет понятие "последнего сообщения" (а ведь у тебя на нем все рассуждение построено), появятся другие поля и задачи. Думаю, для каждой области требуется свое решение и своя структура для хранения данных, универсальности здесь лучше не искать.
Почему же? Если мы будем делать каталог, то все папки можно будет привести к виду "/папка1/папка2 и т.д.", все то же самое.
Давно курил и просветлился, правда реализовать такой алгоритм руки не доходили. А тему закройте, алгоритм неудачный.
Кстати, а если в таблицу добавить столбец, например, sort, по которому будут сортироваться строки во время выборки: [sql]SELECT * FROM tree ORDER BY sort[/sql] А во время изменения дерева использовать такой запрос: [sql]SET @i = 0; UPDATE tree SET sort = (@i := @i + 1) ORDER BY orderby[/sql] Будет ли это целесообразно?
ИПБ не нитевидный. В нем есть кнопочка "Ответить" и быстрый ответ, и что то там "Цитата". При ответе парентом становится последнее сообщение, при цитате - парентом становится пост. при нитевидной организации посты выводятся по времени поста, при дереве - выводятся деревом.