Модераторы: skyboy

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вывести всех родитеей дерева 
:(
    Опции темы
gcc
Дата 3.5.2009, 06:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Агент алкомафии
****


Профиль
Группа: Участник
Сообщений: 2691
Регистрация: 25.4.2008
Где: %&й

Репутация: нет
Всего: 17



нужно вывести всех родителей дерева их id и name?  MySQL
ни где не нашел это

есть столбцы:  id | parent_id | name

сделал рекурсию в скрипте, вывесло, но делает больше 5-10 запросав, сказал что не правильно...

как лучше всего? сделать процедуру в MySQL или еще как-то можно?

может включить кэширвоание и сделать рекурсию обычную? кэширование спасет? оно не будет повтороно для каждого родителя делать запрос?



Это сообщение отредактировал(а) gcc - 3.5.2009, 10:16
PM WWW ICQ Skype GTalk Jabber   Вверх
gcc
Дата 3.5.2009, 09:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Агент алкомафии
****


Профиль
Группа: Участник
Сообщений: 2691
Регистрация: 25.4.2008
Где: %&й

Репутация: нет
Всего: 17



вот нашел
http://cpansearch.perl.org/src/BJEPS/DBIx-Tree-1.9/Tree.pm

оно по-моиму без рекурсии, там можно указать start_id

оно сразу всю таблицу вытаскивает? если да, то это не подхожит...


UPD: нашел http://www.getinfo.ru/article610.html

Это сообщение отредактировал(а) gcc - 3.5.2009, 10:17
PM WWW ICQ Skype GTalk Jabber   Вверх
skyboy
Дата 3.5.2009, 10:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 15
Всего: 260



есть два простых решения: не химичить с тем, что не подходит smile
либо сменить стрктуру хранения на nested sets, либо добавить в каждую запись поле, в котором серализированно хранить идентификаторы всех предков(например, так: "00001.00005.00015.00128").  в обоих случаях для выбора родителей рекурсия не будет нужна.
PM MAIL   Вверх
gcc
Дата 31.7.2009, 15:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Агент алкомафии
****


Профиль
Группа: Участник
Сообщений: 2691
Регистрация: 25.4.2008
Где: %&й

Репутация: нет
Всего: 17



skyboy, при серилизации как мне вывести дерево, точнее всех под разделов с указаного раздела, одим или нескольким запросами?

==============

использую MySQL, MyISA

NestedSet не понравился, говорят он ресурсовемкий если таблица большая, не зря придумывали много для дерева в FriBide, Oracle, etc

и таблицу я создал только c parent_id
если добавить сейчас NestedSet , то переписывать прейдется

не плохой вариант: серилизировать всех родителей каждого дерева

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

может есть смысл innoDB использовать с внешними ключами? только елси там есть реально решения... если оно там есть?
или какой вариант лучше?

Это сообщение отредактировал(а) gcc - 31.7.2009, 15:23
PM WWW ICQ Skype GTalk Jabber   Вверх
skyboy
Дата 31.7.2009, 15:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 15
Всего: 260



Цитата(gcc @  31.7.2009,  14:15 Найти цитируемый пост)
как мне вывести дерево, точнее всех под разделов с указаного раздела, одим или нескольким запросами?

Вывожу потомков раздела с "00007"(типичное значение поля parents: "00003.00007.00010"):
Код

SELECT *
fROM tree
WHERE locate(".00007.",concat(".",parents,"."))> 0

но этот вариант напряжен при выборке: в отличие от одного поля parent_id и пары left_id+right_id в nested sets, сериализированный путь - не индексированное числовое поле. Потому разница в скорости выборки для сериализированного пути и других вариантов должно отличаться уже для небольшого количества элементов(в тысячах), правда, экспериментом подтвердить не могу.
PM MAIL   Вверх
gcc
Дата 31.7.2009, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Агент алкомафии
****


Профиль
Группа: Участник
Сообщений: 2691
Регистрация: 25.4.2008
Где: %&й

Репутация: нет
Всего: 17



я думал что нужно серилизировать только вершние разделы, например от 0007

0001
     0004
        0007

надо нижние тоже серилизировать, а как нижние серилизировать? создаю я подраздел в каком-то разделе, как мне узнать все нижние? ( если всего разделов 1000 и больше, то нужно 1000 UPDATE одним запросом сделать?) (верхние понятно - у родителя)

а есть ли документация? 

я не нашле http://www.google.com.ua/search?hl=uk&...%8C&spell=1





Это сообщение отредактировал(а) gcc - 31.7.2009, 15:44
PM WWW ICQ Skype GTalk Jabber   Вверх
Zloxa
Дата 31.7.2009, 15:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 53
Всего: 161



Nested Sets очень плох на модификации данных. Многопользовательское редактирование можно забыть. Зато дает быстрый селект.
Хранение полного пути к ноде(ранее было, как я понял, названо сериализацией) - одинаково плохо как на выборке, так и на редактировании. Не снимает порбемы многоползовательской модификации.
Самый компромиссный вариант - рекурсия с клиента или хп.
однако не понятно кто "сказал что не правильно" и чем "он" руководствовался.

Это сообщение отредактировал(а) Zloxa - 31.7.2009, 15:50


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
gcc
Дата 31.7.2009, 17:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Агент алкомафии
****


Профиль
Группа: Участник
Сообщений: 2691
Регистрация: 25.4.2008
Где: %&й

Репутация: нет
Всего: 17



ладно тогда nested sets

я вот нашел новые стать:
(не много по другому сделано)
http://habrahabr.ru/blogs/perl/65495/

вот есть на триггерах:
http://habrahabr.ru/blogs/mysql/63883/
http://habrahabr.ru/blogs/postgresql/63416/

не много старые
http://doc.prototypes.ru/database/nestedsets/perl/module/
http://webscript.ru/stories/04/09/01/8197045
PM WWW ICQ Skype GTalk Jabber   Вверх
skyboy
Дата 31.7.2009, 22:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 15
Всего: 260



Цитата(gcc @  31.7.2009,  14:38 Найти цитируемый пост)
надо нижние тоже серилизировать, а как нижние серилизировать?

нет, конечно.
я тебе привел пример запроса выбора всех непосредственных и косвенных потомков.

PM MAIL   Вверх
gcc
Дата 1.8.2009, 06:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Агент алкомафии
****


Профиль
Группа: Участник
Сообщений: 2691
Регистрация: 25.4.2008
Где: %&й

Репутация: нет
Всего: 17



я вот нашел что Firebird хратит ссылку родительский узел

Firebird будет лучше? она бесплтаная вродебы, есть на Linux и FreeBSD 

http://gsbelarus.com/gs/modules.php?name=N...cle&sid=314

Цитата

самый простой способ представления дерева в реляционной базе — это помещение матрицы смежности в таблицу. Каждая запись такой таблицы соответствует узлу дерева и хранит его уникальный идентификатор и ссылку на родительский узел.

Ниже приведен DDL запрос для создания таблицы TEST1 (щелкните по тексту запроса для загрузки его текста в браузер):

CREATE TABLE test1 (
  id INTEGER NOT NULL,
  parent INTEGER,
  
  PRIMARY KEY (id),
  FOREIGN KEY (parent) REFERENCES test1 (id)
    ON UPDATE CASCADE
    ON DELETE CASCADE
);

Обратите внимание на правило ON DELETE CASCADE, заданное для внешнего ключа по полю PARENT. Благодаря нему, при удалении узла будет автоматически удалено и все поддерево, для которого этот узел является корнем. 

PM WWW ICQ Skype GTalk Jabber   Вверх
skyboy
Дата 1.8.2009, 08:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 15
Всего: 260



Цитата(gcc @  1.8.2009,  05:16 Найти цитируемый пост)
я вот нашел что Firebird хратит ссылку родительский узел

ты показываешь такую же стурктуру, о которой говорил в своем первом посте.
PM MAIL   Вверх
gcc
Дата 1.8.2009, 09:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Агент алкомафии
****


Профиль
Группа: Участник
Сообщений: 2691
Регистрация: 25.4.2008
Где: %&й

Репутация: нет
Всего: 17



в первом посте нету
Код

  FOREIGN KEY (parent) REFERENCES test1 (id)
    ON UPDATE CASCADE
    ON DELETE CASCADE
); 


и в первом посте кроме рекурсии практически никак нельзя вынуть вверхние или нижние...?

а тут для извлечения всех потомков узла Р и всех потомков потомков
Код

SELECT id
FROM
  test1
WHERE
  parent = :P
  
UNION
  
SELECT t1.id
FROM
  test1 t1 JOIN test1 t2
    ON t1.parent = t2.id
WHERE
  t2.parent = :P


а чтобы все вложенные уровни для узла с идентификатором, заданным параметром Р

Код

CREATE PROCEDURE RecTest1(AnID INTEGER, Self INTEGER)
  RETURNS (ID INTEGER)
AS
BEGIN
  IF (:Self <> 0) THEN
  BEGIN
    ID = :AnID;
    SUSPEND;
  END
  
  FOR SELECT id FROM test1
  WHERE parent = :AnID INTO :ID
    DO FOR SELECT id FROM RecTest1(:ID, 1) INTO :ID
      DO SUSPEND;
END;

================================

SELECT t.*
FROM test1 t
  JOIN RecTest1(:P, 0) r ON t.id = r.id



там написано что Firebird может рекурсивно это сделать:
Многие сервера баз данных имеют ограничение на максимальное количество рекурсивных вызовов процедуры. Например, для Firebird это ограничение составляет порядка одной тысячи, чего, впрочем, более чем достаточно для выполнения большинства задач

PM WWW ICQ Skype GTalk Jabber   Вверх
skyboy
Дата 1.8.2009, 13:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 15
Всего: 260



Цитата(gcc @  1.8.2009,  08:10 Найти цитируемый пост)
в первом посте нету

ну, так тебе ничто не мешает и под mysql использовать foreign key для каскадного удаления всех потомков при удалении родителя.
Цитата(gcc @  1.8.2009,  08:10 Найти цитируемый пост)
и в первом посте кроме рекурсии практически никак нельзя вынуть вверхние или нижние...?

перебор неограниченной глубины связей можно либо через итерации(через курсоры, видимо, чтоб средствами sql), либо через рекурсию. и твой приведенный запрос для выбора потомков и потомков потомков будет иметь одинаковую функциональность что в firebird, что в mysql. 
если в какой-то СУБД и есть специальный структуры для хранения/обработки графов/деревьев, то пока что про них не было сказано ни слова - список смежности(в виде поля parent_id), сериализацию пути("00001.00008.00010") и Nested Sets можно реализовать в любой СУБД. будь то Firebird или mysql.
и, да, в чем у тебя вопрос? на вопрос 
Цитата(gcc @  3.5.2009,  05:57 Найти цитируемый пост)
как лучше всего?

тебе Zloxa, привел аргументы касательно 3 способов. 
кроме того: ты ищешь "лучшую"(по каким параметрам?) реализацию хранения графа под определенную СУБД(MySQL, судя по первому посту) или ты выбираешь СУБД под хранение графа(то MySQL, то Firebird)?
PM MAIL   Вверх
gcc
Дата 1.8.2009, 13:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Агент алкомафии
****


Профиль
Группа: Участник
Сообщений: 2691
Регистрация: 25.4.2008
Где: %&й

Репутация: нет
Всего: 17



Цитата(skyboy @ 1.8.2009,  13:10)
кроме того: ты ищешь "лучшую"(по каким параметрам?) реализацию хранения графа под определенную СУБД(MySQL, судя по первому посту)

да, я уже выбрал - это NestedSet либо рекурсия, просто хотел спросить, может есть что-то другое, если была СУБД в которой были бы опреаторы для работы с деревом я бы выбрал ее... и с начало надо подумать над архитектурой БД, правильно? например, не рекоммендуется в MySQL использовать рекурсию...

а как этот запрос написать в MySQL чтобы посмотреть всех родителей ввреху (не дерево выводить, а иммено родителей)?
Код

SELECT id
FROM
  test1
WHERE
  parent = :P
  
UNION
  
SELECT t1.id
FROM
  test1 t1 JOIN test1 t2
    ON t1.parent = t2.id
WHERE
  t2.parent = :P

 
не много не понял  parent = :P это тоже самое что и   parent = $p

еще что-то не смог придумать запрос, если у каждого раздела есть поле active (0 или 1 значение)  как изменить у всех подразделов поле active на 1 (тут скорее всего NestedSet...)


Это сообщение отредактировал(а) gcc - 1.8.2009, 13:34
PM WWW ICQ Skype GTalk Jabber   Вверх
Zloxa
Дата 1.8.2009, 17:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 53
Всего: 161



Цитата(gcc @  1.8.2009,  13:32 Найти цитируемый пост)
если была СУБД в которой были бы опреаторы для работы с деревом я бы выбрал ее...

Ты же сам упомянул об этих СУБД


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
gcc
Дата 1.8.2009, 19:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Агент алкомафии
****


Профиль
Группа: Участник
Сообщений: 2691
Регистрация: 25.4.2008
Где: %&й

Репутация: нет
Всего: 17



про каких этих, о Firebird? то есть у нее дерево лучше будет?

там только статьи что-то не нашел на русском, кроме этой  http://gsbelarus.com/gs/modules.php?name=N...cle&sid=314

надо будет на англиской по искать



Это сообщение отредактировал(а) gcc - 1.8.2009, 19:55
PM WWW ICQ Skype GTalk Jabber   Вверх
skyboy
Дата 1.8.2009, 21:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 15
Всего: 260



Цитата(gcc @  1.8.2009,  12:32 Найти цитируемый пост)
если была СУБД в которой были бы опреаторы для работы с деревом я бы выбрал ее...

надо искать. в oracle есть специальные операторы по работе с деревом, если я не ошибаюсь. что, купишь сервер oracle?
может, лучше разбраться с тем же nested sets?
все равно нет универсального "самого лучшего из всех возможных решений" и использование того же oracle проигрывает в переносимости использованию того же nested sets.
PM MAIL   Вверх
Zloxa
Дата 2.8.2009, 10:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 53
Всего: 161



Цитата(skyboy @  1.8.2009,  21:36 Найти цитируемый пост)
купишь сервер oracle

У Оракли есть бесплатная ограниченная версия.
Говорят PG тоже умеет деревья обходить.

Это сообщение отредактировал(а) Zloxa - 2.8.2009, 10:02


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
gcc
Дата 6.8.2009, 03:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Агент алкомафии
****


Профиль
Группа: Участник
Сообщений: 2691
Регистрация: 25.4.2008
Где: %&й

Репутация: нет
Всего: 17



ok посомтрю на PG

ради интереса, такой запрос в принципе тоже првильный?
поставить порядок ступеней (по горизонтале) допустим 50 (хотя можно меньше)

тех элементов которых нету, она прогнорирует?
а в скрипте все что отсутсвует удалить
Код


                                            SELECT t1.id_se AS lvl1,
                              t2.id_se as lvl2, 
                              t3.id_se as lvl3,
                              t4.id_se as lvl4,
                              t5.id_se as lvl5
                                                          t1.id_se AS lvl1,
                              t2.id_se as lvl2, 
                              t3.id_se as lvl3,
                              t4.id_se as lvl4,
                              t5.id_se as lvl5
                                                          t1.id_se AS lvl1,
                              t2.id_se as lvl2, 
                              t3.id_se as lvl3,
                              t4.id_se as lvl4,
                              t5.id_se as lvl5
                                                          t1.id_se AS lvl1,
                              t2.id_se as lvl2, 
                              t3.id_se as lvl3,
                              t4.id_se as lvl4,
                              t5.id_se as lvl5
                                                          t1.id_se AS lvl1,
                              t2.id_se as lvl2, 
                              t3.id_se as lvl3,
                              t4.id_se as lvl4,
                              t5.id_se as lvl5
                                                          t1.id_se AS lvl1,
                              t2.id_se as lvl2, 
                              t3.id_se as lvl3,
                              t4.id_se as lvl4,
                              t5.id_se as lvl5
                                                          t1.id_se AS lvl1,
                              t2.id_se as lvl2, 
                              t3.id_se as lvl3,
                              t4.id_se as lvl4,
                              t5.id_se as lvl5
                                                          t1.id_se AS lvl1,
                              t2.id_se as lvl2, 
                              t3.id_se as lvl3,
                              t4.id_se as lvl4,
                              t5.id_se as lvl5
                                                          t1.id_se AS lvl1,
                              t2.id_se as lvl2, 
                              t3.id_se as lvl3,
                              t4.id_se as lvl4,
                              t5.id_se as lvl5
                                                          t1.id_se AS lvl1,
                              t2.id_se as lvl2, 
                              t3.id_se as lvl3,
                              t4.id_se as lvl4,
                              t5.id_se as lvl5
                                                          t1.id_se AS lvl1,
                              t2.id_se as lvl2, 
                              t48.id_se as lvl48,
                              t49.id_se as lvl49,
                              t50.id_se as lvl50                              
                    FROM section AS t1
             LEFT JOIN section AS t2 ON t2.id_se = t1.parent_se_id
             LEFT JOIN section AS t3 ON t3.id_se = t2.parent_se_id
             LEFT JOIN section AS t4 ON t4.id_se = t3.parent_se_id
             LEFT JOIN section AS t5 ON t5.id_se = t4.parent_se_id    
             LEFT JOIN section AS t6 ON t6.id_se = t6.parent_se_id
             LEFT JOIN section AS t2 ON t2.id_se = t1.parent_se_id
             LEFT JOIN section AS t3 ON t3.id_se = t2.parent_se_id
             LEFT JOIN section AS t4 ON t4.id_se = t3.parent_se_id
             LEFT JOIN section AS t5 ON t5.id_se = t4.parent_se_id    
             LEFT JOIN section AS t6 ON t6.id_se = t6.parent_se_id                         
             LEFT JOIN section AS t2 ON t2.id_se = t1.parent_se_id
             LEFT JOIN section AS t3 ON t3.id_se = t2.parent_se_id
             LEFT JOIN section AS t4 ON t4.id_se = t3.parent_se_id
             LEFT JOIN section AS t5 ON t5.id_se = t4.parent_se_id    
             LEFT JOIN section AS t6 ON t6.id_se = t6.parent_se_id
             LEFT JOIN section AS t2 ON t2.id_se = t1.parent_se_id
             LEFT JOIN section AS t3 ON t3.id_se = t2.parent_se_id
             LEFT JOIN section AS t4 ON t4.id_se = t3.parent_se_id
             LEFT JOIN section AS t5 ON t5.id_se = t4.parent_se_id    
             LEFT JOIN section AS t6 ON t6.id_se = t6.parent_se_id    
             LEFT JOIN section AS t2 ON t2.id_se = t1.parent_se_id
             LEFT JOIN section AS t3 ON t3.id_se = t2.parent_se_id
             LEFT JOIN section AS t4 ON t4.id_se = t3.parent_se_id
             LEFT JOIN section AS t5 ON t5.id_se = t4.parent_se_id    
             LEFT JOIN section AS t6 ON t6.id_se = t6.parent_se_id
             LEFT JOIN section AS t2 ON t2.id_se = t1.parent_se_id
             LEFT JOIN section AS t3 ON t3.id_se = t2.parent_se_id
             LEFT JOIN section AS t4 ON t4.id_se = t3.parent_se_id
             LEFT JOIN section AS t5 ON t5.id_se = t4.parent_se_id    
             LEFT JOIN section AS t6 ON t6.id_se = t6.parent_se_id    
             LEFT JOIN section AS t2 ON t2.id_se = t1.parent_se_id
             LEFT JOIN section AS t3 ON t3.id_se = t2.parent_se_id
             LEFT JOIN section AS t4 ON t4.id_se = t3.parent_se_id
             LEFT JOIN section AS t5 ON t5.id_se = t4.parent_se_id    
             LEFT JOIN section AS t6 ON t6.id_se = t6.parent_se_id
             LEFT JOIN section AS t2 ON t2.id_se = t1.parent_se_id
             LEFT JOIN section AS t3 ON t3.id_se = t2.parent_se_id
             LEFT JOIN section AS t4 ON t4.id_se = t3.parent_se_id
             LEFT JOIN section AS t5 ON t5.id_se = t4.parent_se_id    
             LEFT JOIN section AS t6 ON t6.id_se = t6.parent_se_id    
             LEFT JOIN section AS t2 ON t2.id_se = t1.parent_se_id
             LEFT JOIN section AS t3 ON t3.id_se = t2.parent_se_id
             LEFT JOIN section AS t4 ON t4.id_se = t3.parent_se_id
             LEFT JOIN section AS t5 ON t5.id_se = t4.parent_se_id    
             LEFT JOIN section AS t6 ON t6.id_se = t6.parent_se_id
             LEFT JOIN section AS t2 ON t2.id_se = t1.parent_se_id
             LEFT JOIN section AS t3 ON t3.id_se = t2.parent_se_id
             LEFT JOIN section AS t4 ON t4.id_se = t3.parent_se_id
             LEFT JOIN section AS t49 ON t49.id_se = t49.parent_se_id    
             LEFT JOIN section AS t50 ON t50.id_se = t50.parent_se_id    

                WHERE t1.id_se = start



Это сообщение отредактировал(а) gcc - 6.8.2009, 03:35
PM WWW ICQ Skype GTalk Jabber   Вверх
gcc
Дата 7.8.2009, 00:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Агент алкомафии
****


Профиль
Группа: Участник
Сообщений: 2691
Регистрация: 25.4.2008
Где: %&й

Репутация: нет
Всего: 17



интересует вопрос как работать с дереовм? если таблица неограниченная планируется

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


PM WWW ICQ Skype GTalk Jabber   Вверх
DimW
Дата 7.8.2009, 09:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1330
Регистрация: 24.2.2005
Где: Орёл

Репутация: 4
Всего: 44



Цитата(gcc @  7.8.2009,  00:59 Найти цитируемый пост)
а можно вывести его постранично?

не очень хороший вариант, обычно для дерева реализуется динамическая подгрузка дочерних нодов при выборе родителя. 
PM MAIL ICQ   Вверх
gcc
Дата 7.8.2009, 20:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Агент алкомафии
****


Профиль
Группа: Участник
Сообщений: 2691
Регистрация: 25.4.2008
Где: %&й

Репутация: нет
Всего: 17



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

Это сообщение отредактировал(а) gcc - 7.8.2009, 20:57
PM WWW ICQ Skype GTalk Jabber   Вверх
gcc
Дата 4.10.2009, 17:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Агент алкомафии
****


Профиль
Группа: Участник
Сообщений: 2691
Регистрация: 25.4.2008
Где: %&й

Репутация: нет
Всего: 17



сделал, написал не большую заметку

сейчас думаю над архитектурой еще одного дерева...

мне показалось что NestedSet не подойдет для него так как NestedSet все операции кроме SELECT ресурсоемкие!!

недостатки в Nested Set: если вы заметили, точно такая же рекурсия, только там идет UPDATE ресурсоемкий который все дерево изменяет (очень много записей) по этому я нашел решение где-то на opennet.ru на innodb с ускорением за счет внешних ключей и транзакции (чтобы дерево не развалилось во время изменение структуры). НО еще говорят что если innodb с большой базой, то грузит сильно сервер, неоднократно сталиквался, но в приципе мне все равно,  но тут не знаю, не тестировал... 

про мое дерево долго рассказывать:

1) 

щас нарисую

"Корень дерева" --> "разедел1"
````````````````` "разедел2"->>>"разедел1"
````````````````` "разедел3"````"разедел2"
````````````````` "разедел4"````"разедел3"->>>>>>"разедел1"
````````````````` "разедел5"````````````````````"разедел2"
````````````````` "разедел6"````````````````````"разедел3"
```````````````````````````````````````````````"разедел4"

из этого:
а) у кадого раздела может быть свой "подраздел(ы)"
б) у кадого раздела может быть "тема(ы) сообщения" как на этом форуме
 б2) у темы есть коментарии


думаю все понятно?

2) нужно сделать:
 перенос узла, 
 выборка всех родителей вверх, 
 просмотр
 вывести дерево начиная от како-то элемента,
 удаление/изменение атрибутов всего дерева со всеми подчиненными узлами
 если ничего не забыл, может еще что-то
 
 все дерево выносить не надо

===
при обычном parent_id:

id
parent_id
(можно еще level)

Преимущества дерева
1) перенос 
2) Добавление
3) Нормальный SELECT и SELECT всех родителей  (SELECT сразe 50-100 ступеней можно сделать,( т.е. ограничить) а лишние удалить, либо рекурсию) все остальное нормально

Недостатки:
1) удаление всего дерева затруднительно (рекурсию надо делать, или процедуру)
  НО в условии, например присутствует, что пользователи не могут когда они захотят все удалить, литит удлаения должен быть (проблем не будет)
2) узменение атрибута узла и всего поддерева (например надо все дерево скрыть начиная с конкретного узла) (рекурсию надо делать, или триггер)

можно записывать level уровень, чтобы сделать еше быстрый SELECT всех родителей и  в один НОРМАЛЬНЫЙ запрос

т.е. исходя их этого например при обычном NestedSET, пвсе запросы (почти все, удаление, добавление, перенос) ресурсоемкое, но кроме SELECT
в этом случае который я привел, грубо говоря, только удаление ресурсоемкое!

вообщем, как? 
писал старался, хотел узнать может есть замечания какие-то?

Это сообщение отредактировал(а) gcc - 4.10.2009, 17:45
PM WWW ICQ Skype GTalk Jabber   Вверх
DimW
Дата 5.10.2009, 07:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1330
Регистрация: 24.2.2005
Где: Орёл

Репутация: 4
Всего: 44



Цитата(gcc @  4.10.2009,  17:44 Найти цитируемый пост)
Недостатки:
1) удаление всего дерева затруднительно (рекурсию надо делать, или процедуру)


Цитата(gcc @  4.10.2009,  17:44 Найти цитируемый пост)
можно записывать level уровень, 

этих проблем в принципе не существует(изучите ниже приведенный пример для оракл):
Код

SQL> create table TABLE1
  2  (ID        NUMBER not null,
  3   PARENT_ID NUMBER);
 
Table created
SQL> alter table TABLE1
  2    add constraint TABLE1_PK primary key (ID);
 
Table altered
SQL> alter table TABLE1
  2    add constraint TABLE1_FK foreign key (PARENT_ID)
  3    references TABLE1 (ID) on delete cascade;
 
Table altered
SQL> insert into table1 (id, parent_id) values (1, null);
 
1 row inserted
SQL> insert into table1 (id, parent_id) values (2, 1);
 
1 row inserted
SQL> insert into table1 (id, parent_id) values (3, 1);
 
1 row inserted
SQL> insert into table1 (id, parent_id) values (4, 1);
 
1 row inserted
SQL> insert into table1 (id, parent_id) values (5, 4);
 
1 row inserted
SQL> insert into table1 (id, parent_id) values (6, 4);
 
1 row inserted
SQL> insert into table1 (id, parent_id) values (7, 4);
 
1 row inserted
SQL> select level
  2        ,lpad(t.id, level*4, '-') tree
  3        ,sys_connect_by_path(id, '/') path -- показывает путь от родителя до текущего нода
  4    from table1 t
  5  start with t.parent_id is null
  6  connect by prior t.id = t.parent_id;
 
     LEVEL TREE                                                                             PATH
---------- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
         1 ---1                                                                             /1
         2 -------2                                                                         /1/2
         2 -------3                                                                         /1/3
         2 -------4                                                                         /1/4
         3 -----------5                                                                     /1/4/5
         3 -----------6                                                                     /1/4/6
         3 -----------7                                                                     /1/4/7
 
7 rows selected
SQL> delete table1 where id = 1;
 
1 row deleted
SQL> select * from table1;
 
        ID  PARENT_ID
---------- ----------
 
SQL> 


обратите на организацию связи: references TABLE1 (ID) on delete cascade
обратите внимание на это-  sys_connect_by_path и на это - select level




Это сообщение отредактировал(а) DimW - 5.10.2009, 07:46
PM MAIL ICQ   Вверх
gcc
Дата 5.10.2009, 08:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Агент алкомафии
****


Профиль
Группа: Участник
Сообщений: 2691
Регистрация: 25.4.2008
Где: %&й

Репутация: нет
Всего: 17



DimW, я вот тоже нашел http://www.opennet.ru/base/dev/hierarchy_sql.txt.html  только там под Interbase, заточить по-моему можн под MySQL

Цитата(DimW @ 5.10.2009,  07:44)
обратите на организацию связи: references TABLE1 (ID) on delete cascade

в MyISAM таблицых в MySQL такого нету...
у меня сейчас таблица именно такая

спасибо, посомтрю, с Oracle не работал никогда, буду иметь ввиду на PgSQL... или на innodb

====

я вот как раз хотел оптимизировать DELETE на MySQL
(кроме временных таблиц - это сделал)

Есть таблица составных деталей с "древесной" структурой, т.е. код/код предка/название, например:
Код

CREATE  tree (i, parent_id i, name c(10))
INSERT INTO tree VALUES (1,0,'Деталь1')
INSERT INTO tree VALUES (2,0,'Деталь2')
INSERT INTO tree VALUES (3,2,'Деталь3')
INSERT INTO tree VALUES (4,2,'Деталь4')
INSERT INTO tree VALUES (5,4,'Деталь5')
INSERT INTO tree VALUES (6,4,'Деталь6')
INSERT INTO tree VALUES (7,5,'Деталь7')

Как в такой таблице красиво сделать рекурсивное удаление всех потомков при удалении записи (чтобы при удалении детали №4 удалились детали №5,6,7)? 


вот я это нашел... http://forum.foxclub.ru/read.php?29,400359,400507 только там под Interbase, заточить по-моему можн под MySQL

например на  Visual Foxpro:
Код

DelTree (2)

PROCEDURE DelTree (tnID)
LOCAL laChilds[1], ln1
SELECT det_id FROM tree WHERE parent_id = m.tnID INTO ARRAY laChilds
FOR ln1 = 1 TO _TALLY
DelTree (laChilds[m.ln1])
ENDFOR
DELETE FROM tree WHERE det_id = m.tnID
ENDPROC


но как написать это на MySQL, например, на триггерах или процедурах?

не могу понять как это сделать вообще, путаюсь...




Это сообщение отредактировал(а) gcc - 5.10.2009, 08:34
PM WWW ICQ Skype GTalk Jabber   Вверх
Deniz
Дата 5.10.2009, 08:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1251
Регистрация: 16.10.2004
Где: Новый Уренгой

Репутация: 6
Всего: 44



Код
SQL> delete table1 where id = 1;
 
1 row deleted
Oracle не выводит кол-во реально удаленных записей? Ведь реально было удалено 7 записей.

Цитата(gcc @  5.10.2009,  11:18 Найти цитируемый пост)
но как написать это на MySQL, например, на триггерах или процедурах?
на триггерах можно примерно так:
Код
delete from TableName where parent = ID_deleted_record



--------------------
"Для того чтобы сделать шаг вперед, достаточно пинка сзади" (с)
PM ICQ   Вверх
DimW
Дата 5.10.2009, 08:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1330
Регистрация: 24.2.2005
Где: Орёл

Репутация: 4
Всего: 44



Цитата(gcc @  5.10.2009,  08:18 Найти цитируемый пост)
в MyISAM таблицых в MySQL такого нету...

что такое MyISAM я не знаю, но дока по mysql говорит что каскадное удаление есть: http://dev.mysql.com/doc/refman/5.1/en/inn...onstraints.html
PM MAIL ICQ   Вверх
Deniz
Дата 5.10.2009, 08:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1251
Регистрация: 16.10.2004
Где: Новый Уренгой

Репутация: 6
Всего: 44



FireBird пропускает такие триггеры


--------------------
"Для того чтобы сделать шаг вперед, достаточно пинка сзади" (с)
PM ICQ   Вверх
DimW
Дата 5.10.2009, 09:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1330
Регистрация: 24.2.2005
Где: Орёл

Репутация: 4
Всего: 44



Цитата(Deniz @  5.10.2009,  08:50 Найти цитируемый пост)
Oracle не выводит кол-во реально удаленных записей?

при такой организации связи нет.
PM MAIL ICQ   Вверх
skyboy
Дата 5.10.2009, 09:01 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 15
Всего: 260



Цитата(DimW @  5.10.2009,  07:53 Найти цитируемый пост)
что такое MyISAM я не знаю

MyISAM - это технология(в документации mysql называется "движком" - Engine), которая определяет особенности хранения данных и работы с ними. Определяется в отдельности на каждую таблицу. С точки зрения SQL-запроса является прозрачным. Но накладывает ограничения. К примеру, MyISAM не поддерживает транзакции и внешние ключи.
PM MAIL   Вверх
DimW
Дата 5.10.2009, 09:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1330
Регистрация: 24.2.2005
Где: Орёл

Репутация: 4
Всего: 44



Цитата(skyboy @  5.10.2009,  09:01 Найти цитируемый пост)
MyISAM - это технология(в документации mysql называется "движком" - Engine), 

понял, спасибо, по крайней мере теперь дубу обращать внимание на подобного рода абривиатуры smile

skyboy, может и по поводу каскадного удаления прояснишь, тоже не поддерживается?
PM MAIL ICQ   Вверх
gcc
Дата 5.10.2009, 09:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Агент алкомафии
****


Профиль
Группа: Участник
Сообщений: 2691
Регистрация: 25.4.2008
Где: %&й

Репутация: нет
Всего: 17



DimW,  вот тут вот есть не много

http://ru.wikipedia.org/wiki/MyISAM
http://xpoint.ru/forums/computers/dbms/mys...ead/36704.xhtml

в MyISAM есть fulltext index поиск можно сделать с релевантностью

PM WWW ICQ Skype GTalk Jabber   Вверх
DimW
Дата 5.10.2009, 09:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1330
Регистрация: 24.2.2005
Где: Орёл

Репутация: 4
Всего: 44



Цитата(DimW @  5.10.2009,  09:08 Найти цитируемый пост)
skyboy, может и по поводу каскадного удаления прояснишь, тоже не поддерживается?

не отвечай в доке ясно написано: 
Цитата

InnoDB supports foreign key constraints. The syntax for a foreign key constraint definition in InnoDB looks like this: ..........


Цитата(gcc @  5.10.2009,  08:18 Найти цитируемый пост)
или на innodb


gcc, так что можете использовать в innodb каскадное удаление.

Добавлено через 3 минуты и 19 секунд
Цитата(gcc @  5.10.2009,  09:19 Найти цитируемый пост)
http://ru.wikipedia.org/wiki/MyISAM

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

Добавлено через 7 минут и 43 секунды
походу из плюсов MyISAM только быстрое чтение и быстрая крос-переносимость.
PM MAIL ICQ   Вверх
gcc
Дата 5.10.2009, 10:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Агент алкомафии
****


Профиль
Группа: Участник
Сообщений: 2691
Регистрация: 25.4.2008
Где: %&й

Репутация: нет
Всего: 17



про внешние ключи забыл вообще...

тогда поставлю innodb
PM WWW ICQ Skype GTalk Jabber   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Составление SQL-запросов | Следующая тема »


 




[ Время генерации скрипта: 0.0863 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.