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

Форум MySQL

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

 

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

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

тема: Хранение древовидных структур в БД
 
 автор: pengo   (03.08.2006 в 11:48)   письмо автору
 
 

Здравствуйте.
Недавно я столкнулся с проблеммой хранения деревьев в базе данных. Естественно начал поиски в интернете и набрёл на интересную статью http://phpclub.ru/detail/article/db_tree.
Всё бы и хорошё, но я столкнулся с проблеммной добовления ветвей в уже существующее дерево. В классе, который там описан, данная функция отсутствует, а в SQL я недостаточно силён. Может кто подскажет, как по всем правилам добавлять ветви в нужное мне место.

   
 
 автор: pengo   (03.08.2006 в 11:53)   письмо автору
 
   для: pengo   (03.08.2006 в 11:48)
 

хотя вот есть там такое:

function insert($ID, $data) 
Метод для вставки узла в дерево. Параметры: 
$ID - идентификатор родительского узла 
$data - массив с обновленными данными. (параметры left, right и level вставлять не нужно)


но как это использовать в программе?

   
 
 автор: akira   (03.08.2006 в 12:16)   письмо автору
 
   для: pengo   (03.08.2006 в 11:53)
 

Я бы посоветовал измененный класс DBtree
>но как это использовать в программе?

function insert(0, "Второй элемент"); // Где 0 ID родителя

   
 
 автор: cheops   (03.08.2006 в 12:20)   письмо автору
 
   для: pengo   (03.08.2006 в 11:48)
 

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

   
 
 автор: pengo   (03.08.2006 в 12:27)   письмо автору
 
   для: cheops   (03.08.2006 в 12:20)
 

>Зачем всё усложнять, можно просто использовать одну таблицу в которой имеется первичный ключ и вторичный ключ, ссылающийся на первичный и добавлять новые записи по мере необходимости

Я тоже к этому склоняюсь.
Может тогда подскажите, как на PHP организовать рекурсивную процедуру для вывода потомков для указанного родителя.

   
 
 автор: cheops   (03.08.2006 в 12:31)   письмо автору
 
   для: pengo   (03.08.2006 в 12:27)
 

С удовольствием, только уточните пожалуйста формат - как их выводить? Лестнично?

   
 
 автор: pengo   (03.08.2006 в 12:39)   письмо автору
 
   для: cheops   (03.08.2006 в 12:31)
 

наверное лестнично. В принципе с выводом можно будет самому поиграться. Буду весьма признателен.
Есчё, если можно, SQL-дамп таблицы.

   
 
 автор: cheops   (03.08.2006 в 13:54)   письмо автору
 
   для: pengo   (03.08.2006 в 12:39)
 

Пусть у нас имеется таблица, которая содержит первичный ключ id и вторичный ключ parent, который содержит значение id родителя (если это корневой каталог и родителя нет - принимает значение 0). Тогда функция рекурсивного спуска может выглядять так
<?php 
  
function recurse($id$count
  { 
    
$count += 5;
    
$query "SELECT * FROM tbl WHERE parent = $id";
    
$tbl mysql_query(); 
    if(!
$tbl) exit("Ошибка синтаксиса ".mysql_error()); 
    if(
mysql_num_rows($tbl) > 0
    { 
      while(
$table mysql_fetch_array($tbl)) 
      { 
        echo 
str_repeat("&nbps;"$count).$table['name']."<br>";
        
recurse($table['id'], $count); 
      } 
    } 
  } 
  
recurse(00$count);
?>

   
 
 автор: pengo   (03.08.2006 в 13:57)   письмо автору
 
   для: cheops   (03.08.2006 в 13:54)
 

спасибо!

   
 
 автор: pengo   (03.08.2006 в 14:13)   письмо автору
 
   для: cheops   (03.08.2006 в 13:54)
 

а почему

recurse(0, 0, $count);

ведь функция принимает только два параметра?

   
 
 автор: cheops   (03.08.2006 в 16:57)   письмо автору
 
   для: pengo   (03.08.2006 в 14:13)
 

Конечно же имеется ввиду вызов
 recurse(0, 0);

   
 
 автор: pengo   (04.08.2006 в 12:20)   письмо автору
 
   для: cheops   (03.08.2006 в 16:57)
 

Уважаемый cheops, а если мне необходимо спуститься по дереву не больше чем на 5 вложений. Как тогда организовать функцию.

   
 
 автор: cheops   (04.08.2006 в 12:58)   письмо автору
 
   для: pengo   (04.08.2006 в 12:20)
 

Проверяёте значение $count внутри функции - если оно больше 25, покидайте функцию при помощи оператора return.

   
 
 автор: Axxil   (04.08.2006 в 12:53)   письмо автору
 
   для: cheops   (03.08.2006 в 13:54)
 

// поправленый вариант 
echo str_repeat("&nbsp;", $count).$table['name']."<br>"; 
Я так понимаю это дерево можно применять для организауии каталогов любого уровня вложенности. А можно ли это дело как-то оптимизировать, чтоб не нагружать сильно базу.
И вообще как такие деревья оптимизируют?
И в итоге что быстрее и лучше. Куча маленьких запросов или один большой? Что быстрее базу завалит?

   
 
 автор: Loki   (03.08.2006 в 13:59)   письмо автору
 
   для: cheops   (03.08.2006 в 12:20)
 

Чтобы избежать рекурсии.

   
 
 автор: pengo   (04.08.2006 в 10:14)   письмо автору
 
   для: Loki   (03.08.2006 в 13:59)
 

Насколько я знаю, чтобы избежать рекурсии, придёться использовать вложенные процедуры в SQL-запросах.

   
 
 автор: Loki   (04.08.2006 в 13:21)   письмо автору
 
   для: pengo   (04.08.2006 в 10:14)
 

есть варианты. Как я уже сказал, можно использовать nested sets, можно завести поле со структурой дерева, можно рекурсию переложить целиком на php, оставив всего один запрос к базе, а можно использовать несколько левых объединений. Так что можно и без вложенных процедур:)

   
 
 автор: Axxil   (04.08.2006 в 13:24)   письмо автору
 
   для: Loki   (04.08.2006 в 13:21)
 

> рекурсию переложить целиком на php оставив всего один запрос к базе

select * from tbl

:)

с тем же успехом можно вообще базой не пользоваться. А хранить в тектовом файле.

   
 
 автор: Loki   (04.08.2006 в 13:37)   письмо автору
 
   для: Axxil   (04.08.2006 в 13:24)
 

на самом деле

select id, parent_id, name from tbl 

а таблица может иметь еще сотню полей, так что с тем же успехом не получится:)

   
Rambler's Top100
вверх

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