Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Древо иерархии...
 
 автор: dimon.st   (26.02.2006 в 19:09)   письмо автору
 
 

Здравствуйте, всвязи с моим поистине наполеоновским планом изобретения велосипеда, точнее создания своего форума появился вопрос. Хочется создать систему основанную на иерархии как разделов форума, так и самих сообщений, вроде не так чтобы сложно, ведь система хранения структуры в базах данных уже на каждом заборе описанна (имеется ввиду система, где для каждой строчки сушествует индентификатор и индетификатор родительского раздела), но меня смутила одна вещь: построение этой самой полной иерархии:
1. Способ предлагаемый в статьях: рекрусивная функция каждый раз вызывающая обращение к sql, и выводящая соответственные результаты, по-моему лишние пара сотен запросов это плохо.
2. Получить все записи и "туда сюда" средствами пхп, но проблеммы:
1) Извлечение части иерархии, ведь объяснить sql'у что я хочу 10 записей "вот этих", а не весь дамп затруднительно.. Может можно как то написать сложный многоуровневый запрос выясняющий id и pid???
2) Сортировка их в правильном порядке. Это конечно вполне решабельно, правда перспектива рисования этой самой сортировки меня не восхищает в полной мере)...
Зарание спасибо....

   
 
 автор: cheops   (26.02.2006 в 23:51)   письмо автору
 
   для: dimon.st   (26.02.2006 в 19:09)
 

У вам будет поддерживаться лестничная структура как у нас или будет только линейная структура как в phpBB?

   
 
 автор: Dimon.st   (27.02.2006 в 00:31)   письмо автору
 
   для: cheops   (26.02.2006 в 23:51)
 

Будет... а черт его знает что получится... хочу я и то и то, но повторить структуру бб проблем вообще не представляет, а вот сделать как у вас это оказалось очень даже не просто...

   
 
 автор: cheops   (27.02.2006 в 00:42)   письмо автору
 
   для: Dimon.st   (27.02.2006 в 00:31)
 

Лучше рекурсивно спускайтесь, другим путём ещё хуже получится...

   
 
 автор: Dimon.st   (27.02.2006 в 00:52)   письмо автору
 
   для: 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... как это реализовать честно скажу не знаю, зато хорошие перспективы...

   
 
 автор: JC_Piligrim   (27.02.2006 в 01:03)   письмо автору
 
   для: Dimon.st   (27.02.2006 в 00:52)
 

Не уверен точно, но мне кажется, что без извлечения всего дерева не получится. Во всяком случае я такого способа пока не знаю, хотя очень буду рад, если он есть и кто-то сможет рассказать, как это сделать. В добавок ко 2-му пункту могу предложить небольшую оптимизацию.

Не хранить данные и дерево в одной таблице, а разделить их. Т.е. сделать 2 таблицы, типа:

table tree:
id, pid, data_id

table data:
id, text, date, user ...

Т.е., в первой таблице будет только структура данных, которую будем читать целиком. (также там будет храниться указатель на сообщение из таблицы данных) А во втором - сами данные.

Но, конечно, если есть решение на чистом SQL - было бы гораздо лучше и изящнее.

   
 
 автор: Dimon.st   (27.02.2006 в 01:08)   письмо автору
 
   для: JC_Piligrim   (27.02.2006 в 01:03)
 

Мне по душе этот вариан, честно.. Спасибо. Насчет sql, ради этого изящно - весь день сижу читаю учебники... интресно... местами... Чувствую и завтра буду заниматься тем же...
Кстати cheops, а как работает этот форум?

   
 
 автор: Loki   (27.02.2006 в 11:05)   письмо автору
 
   для: JC_Piligrim   (27.02.2006 в 01:03)
 

Тут натыкался на статью о построении дерева без рекурсии. Идея была в том, что в БД содержалось поле вида "0000111000". Где каждый символ обозначал уровень в дереве, а значение... вот тут забыл - не то родителя, не то просто порядок... Короче, статью я прочел по диагонали, но так как самостоятельно такого не делал, то в голове отложилось только то, что способ есть. Ну и кроме того он имеет какие-то специфические ограничения.

   
 
 автор: Dimon.st   (27.02.2006 в 13:10)   письмо автору
 
   для: 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 тот номер иерархии...

   
 
 автор: Loki   (27.02.2006 в 13:18)   письмо автору
 
   для: 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 

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

   
 
 автор: Dimon.st   (27.02.2006 в 13:39)   письмо автору
 
   для: 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 будет тем же, но в обратном порядке...

   
 
 автор: Loki   (27.02.2006 в 13:50)   письмо автору
 
   для: Dimon.st   (27.02.2006 в 13:39)
 

Просто моя реализация уходит от рекурсии, а ваша - нет:)

   
 
 автор: Dimon.st   (27.02.2006 в 19:54)   письмо автору
 
   для: 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>';} //построение 
?>

   
 
 автор: Loki   (27.02.2006 в 22:00)   письмо автору
 
   для: Dimon.st   (27.02.2006 в 19:54)
 

Да. Вы правы. Я понял принцип работы несколько неправильно...
Но у вас в запросе ошибка. Должно быть

SELECT * FROM 'temp' WHERE'fid' LIKE '|$fid|%' ORDER BY 'fid'

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования