|
|
|
| Здравствуйте, всвязи с моим поистине наполеоновским планом изобретения велосипеда, точнее создания своего форума появился вопрос. Хочется создать систему основанную на иерархии как разделов форума, так и самих сообщений, вроде не так чтобы сложно, ведь система хранения структуры в базах данных уже на каждом заборе описанна (имеется ввиду система, где для каждой строчки сушествует индентификатор и индетификатор родительского раздела), но меня смутила одна вещь: построение этой самой полной иерархии:
1. Способ предлагаемый в статьях: рекрусивная функция каждый раз вызывающая обращение к sql, и выводящая соответственные результаты, по-моему лишние пара сотен запросов это плохо.
2. Получить все записи и "туда сюда" средствами пхп, но проблеммы:
1) Извлечение части иерархии, ведь объяснить sql'у что я хочу 10 записей "вот этих", а не весь дамп затруднительно.. Может можно как то написать сложный многоуровневый запрос выясняющий id и pid???
2) Сортировка их в правильном порядке. Это конечно вполне решабельно, правда перспектива рисования этой самой сортировки меня не восхищает в полной мере)...
Зарание спасибо.... | |
|
|
|
|
|
|
|
для: dimon.st
(26.02.2006 в 19:09)
| | У вам будет поддерживаться лестничная структура как у нас или будет только линейная структура как в phpBB? | |
|
|
|
|
|
|
|
для: cheops
(26.02.2006 в 23:51)
| | Будет... а черт его знает что получится... хочу я и то и то, но повторить структуру бб проблем вообще не представляет, а вот сделать как у вас это оказалось очень даже не просто... | |
|
|
|
|
|
|
|
для: Dimon.st
(27.02.2006 в 00:31)
| | Лучше рекурсивно спускайтесь, другим путём ещё хуже получится... | |
|
|
|
|
|
|
|
для: cheops
(27.02.2006 в 00:42)
| | К примеру такая иерархия:
--------------------------------------------------------------------------------------------------
|id|fid| title
--------------------------------------------------------------------------------------------------
|1|0|Главное сообщение (топик)
|2|1|Ответ на топик
|3|1|Ответ на топик №2
|4|2|Ответ на сообщение 2
|5|3|Ответ на сообщение 3
|6|4|Ответ на сообщение 4, которое в свою очередь является ответом на сообщение 2
---------------------------------------------------------------------------------------------------
|
Я вообще думал о 3 способах:
1. Рекрусивная функция - не разумно я думаю, вследствии колличества запросов к sql всеже лишнее 50 запросов, это не дело...
2. Извлечь все строчки.. и далее сортинг на PHP, проблемма: в таблице содержится много сообщений, в том числе и на другие топики, решение: ввод дополнительного поля для обозначения одного сообщения. Минусы: сортинг на пхп, извлечение десятков ненужнужных впоследствии записей
3. Извлечение какого-то отрывка этой иерархии средствами языка sql, если такое вообще реально... Например, с сообщения 1 это все сообщения, а с 2 это 2,4,6... как это реализовать честно скажу не знаю, зато хорошие перспективы... | |
|
|
|
|
|
|
|
для: Dimon.st
(27.02.2006 в 00:52)
| | Не уверен точно, но мне кажется, что без извлечения всего дерева не получится. Во всяком случае я такого способа пока не знаю, хотя очень буду рад, если он есть и кто-то сможет рассказать, как это сделать. В добавок ко 2-му пункту могу предложить небольшую оптимизацию.
Не хранить данные и дерево в одной таблице, а разделить их. Т.е. сделать 2 таблицы, типа:
table tree:
id, pid, data_id
table data:
id, text, date, user ...
Т.е., в первой таблице будет только структура данных, которую будем читать целиком. (также там будет храниться указатель на сообщение из таблицы данных) А во втором - сами данные.
Но, конечно, если есть решение на чистом SQL - было бы гораздо лучше и изящнее. | |
|
|
|
|
|
|
|
для: JC_Piligrim
(27.02.2006 в 01:03)
| | Мне по душе этот вариан, честно.. Спасибо. Насчет sql, ради этого изящно - весь день сижу читаю учебники... интресно... местами... Чувствую и завтра буду заниматься тем же...
Кстати cheops, а как работает этот форум? | |
|
|
|
|
|
|
|
для: JC_Piligrim
(27.02.2006 в 01:03)
| | Тут натыкался на статью о построении дерева без рекурсии. Идея была в том, что в БД содержалось поле вида "0000111000". Где каждый символ обозначал уровень в дереве, а значение... вот тут забыл - не то родителя, не то просто порядок... Короче, статью я прочел по диагонали, но так как самостоятельно такого не делал, то в голове отложилось только то, что способ есть. Ну и кроме того он имеет какие-то специфические ограничения. | |
|
|
|
|
|
|
|
для: Loki
(27.02.2006 в 11:05)
| | Придумал, вот еще вариант, оцените:
1 |1| mes
2 |1|2| ans 1
3 |1|3| ans 2
4 |1|2|4| ans for 2 - II
5 |1|5| ans 3
6 |1|2|4|6| ans for 4 for 2 - III
7 |1|2|4|6|7| ans for 6 for 4 for 2 - IV
8 |8| mes
9 |8|9| reply
10 |8|9|10| reply for reply
Тогда обычным sql запросом с регулярным выражением мы получаем что хотели:
SELECT * FROM 'temp' WHERE('fid' LIKE '%|x|%' ORDER BY 'fid'), где x тот номер иерархии... | |
|
|
|
|
|
|
|
для: Dimon.st
(27.02.2006 в 13:10)
| | мне кажется, что правильнее было бы так:
|1| mes
|2|1| ans 1
|3|1| ans 2
|4|0|3| ans for 2 - II
|5|1| ans 3
|6|0|0|3| ans for 4 for 2 - III
|7|0|0|0|3| ans for 6 for 4 for 2 - IV
|8| mes
|9|8| reply
|10|0|8| reply for reply
|
Такой вариант мне кажется более наглядным и будет чуть проще в реализации. | |
|
|
|
|
|
|
|
для: Loki
(27.02.2006 в 13:18)
| | Несовсем, при такой реализации с нулями, вы не сможете получить полную иерархию ответов, то есть:
1
-1.1
-1.2
--1.2.1
---1.2.1.1 ------------ это сообщение будет в конце
--1.2.2
---1.2.2.1
и нельзя выделить все сообщения относящиеся к одному топику, для этого надо дописать еще один номер в fid в конец, но тогда fid будет тем же, но в обратном порядке... | |
|
|
|
|
|
|
|
для: Dimon.st
(27.02.2006 в 13:39)
| | Просто моя реализация уходит от рекурсии, а ваша - нет:) | |
|
|
|
|
|
|
|
для: Loki
(27.02.2006 в 13:50)
| | Уважаемый, поясните, где здесь рекрусия??
<?
$fid=1; //id элемента с какого начинаем извлекать иерархию
$result=mysql_query("SELECT * FROM 'temp' WHERE('fid' LIKE '%|$fid|%' ORDER BY 'fid')"); //извлечение иерархии, без надобности последующий сортировки
while($temp=mysql_fetch_assoc($result))
{print $temp['title'].'<br>';} //построение
?>
|
| |
|
|
|
|
|
|
|
для: Dimon.st
(27.02.2006 в 19:54)
| | Да. Вы правы. Я понял принцип работы несколько неправильно...
Но у вас в запросе ошибка. Должно быть
SELECT * FROM 'temp' WHERE'fid' LIKE '|$fid|%' ORDER BY 'fid'
|
| |
|
|
|