Написание модуля или модели для работы с деревьями NESTED

Добрый день!

Возникла задача написать скрипты для работы с деревьями NESTED SETS.

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

База данных: MySQL

OS: Ubuntu 8.10

Что? никто ещё не разобрался?  ;)

Quote

Добрый день!

Возникла задача написать скрипты для работы с деревьями NESTED SETS.

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

По идеологии Yii, в случае если для решения задачи нужно использовать несколько контроллеров и т.д., но логически все это решает одну задачу, то можно сделать в виде модуля.

Quote

ну естественно и что бы была возможность работать с разными таблицами базы данных.

Можно написать behavior. Насколько мне известно класс для работы с деревьями планируется в следующих версиях Yii. Возможно это объясняет отсутствие такового в extensions. Ведь лучше qiang врятли кто-то напишет.

Но если нужно уже, то как вариант можно переписать существующие behaviors моделей из других фреймворков под Yii, например из CakePHP.

NestedSets не люблю.

Сейчас работаю с GiST, думаю в скором времени кину механизм для работы с этим деревом (ltree)

Quote

NestedSets не люблю.

Сейчас работаю с GiST

можете более подробно объяснить о технологии либо же дать ссылки на ресурсы где можно было бы почерпнуть инфы  ???

Конечно,

технология этого дерева используется в поисковике рамблер, написано оно на постгресе и представляет из себя огромный функционал для работы. Всевозможные выборки разных ветвей, склеивания, исключение из выборок и тп - выполняются одним запросом, все остальное делает сам gist на уровне постгреса. сама технология добавляет в таблицу где вам надо дерево - поле path (типа ltree к примеру) который имеет вид вложености к примеру:

id path

1 .

2 1.

3 1.2.

4 1.2.

5 1.

само поле path вам не надо генерировать и заполнять самому. ltree сам дает нам обвертку над селектом которая позволяет нам к примеру написать select path from test where path <@ '1.2'; мы получим все узлы ветки 1.2 и тп. короче очень серьезный инструмент для серьезных проектов.

минусы nested sets в том чтобы вставить новый узел во внутриность дерева - все ключи приходится переписывать. а что если узлов тысячи - сами понимаете. поэтому нестед сразу отпадает для больших проектов где часто используются вставки в дерево.

вот хорошая дока с примерами (правда на англ.) http://www.sai.msu.s…res/gist/ltree/

понято, лично для меня этот вариант отпадает, поскольку я использую MySQL.

ну а что касается Тested Sets - да, ключи нужно переписывать, но! кто или что мешает написать класс (модуль) для этого? Плюс ко всему вставки будут производится намного реже нежели выборки и построение деревца ;)

да суть не в том что надо переписывать ключи и что проблемно это реализовать.

нестед три делает для этого простые запросы и ключи берут и переписываются. проблемы в том:

  1. сразу несколько вставок в дерево. ключи побежали переписыватся и тут ктото вставил еще - может упасть дерево нефиг делать. а использовать транзакции - ну имхо не стоит того т.к. другим прийдется ожидать а при нагруженых системах это очень не "вкусное" решение

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

есть два на сегоднешний день актуальных решений деревьев на мускуле - нестед три и id/idOwner. в первом варианте - дерево надо использовать если вы чаще выводите дерево чем в него вставляете/обновляете. второй вариант - в случае на оборот. если вставки идут частые но вывод ВСЕГО дерева идет редко.

Quote

Плюс ко всему вставки будут производится намного реже нежели выборки и построение деревца ;)

как раз таки в нестед сетс вставки намного больше дают нагрузки на базу чем выборка веток и построение дерева. в этом и фишка нестед сетс =)

Quote

NestedSets не люблю.

Сейчас работаю с GiST…

Что за бред? Алгоритма с названием "GiST" по работе с деревьями не существует, то что вы описываете это всем хорошо известный Materialized Path. Любить или не любить тот или иной алгоритм для работы с деревьями по крайней мере нерационально. Каждый из них (а их всего 3, либо комбинация 2-ух из этих 3) оптимально подходит для решения своих задач. Для задач различного уровня актуальны все 3: Materialized Path, Nested Sets и Adjacency List.

Михаил Стадник дал неплохой обзор данных алгоритмов в своем блоге.

to creocoder

я дал ссылку на гист выше. почитайте.

это не алгоритм, а реализация btree (которое пусть работает по алгоритму Materialized Path как вы сказали) дерева на PostgreSQL. составляет в себя кучу встаивающихся в постгрес хранимых процедур которые облегчают работу с данным алгоритмом и позваляют осуществлять выборки любой сложности в 1-2 запроса. при этом не требует от разработчика самому менять path и тп.

и не вам рассказывать рационально что-то любить или нет. моё видинье я описал, с нестед сетс работал долго и делаю из этого соотвественные выводы. так что ненадо тут с пеной у рта рассказать что кому писать, не нравится моё виденье - игнорируйте мои посты. дальше вступать в дискуссию не намерен.

Класс! в споре рождается истина! только вот спор немного не в тему. :o

я спросил у общественности как буде правильно с точки зрения файловой структуры и по логике вещей написать модуль для управления деревьями Nested Sets  ;)

Quote

Класс! в споре рождается истина! только вот спор немного не в тему. :o

я спросил у общественности как буде правильно с точки зрения файловой структуры и по логике вещей написать модуль для управления деревьями Nested Sets  ;)

Моё видинье на этот счет что можно создать простую модель с функционалом (методами) добавления/удаления/выборки/перемещения. сделать что б tableName было динамическим значением и которое можно было бы инициализировать перед работой с моделью. вот и все. надо будет работать с таблицей "test" к примеру у которой есть дерево, делаете:

$tree = new TreeModel();

$tree->setTable('test');

$tree->select(…)

ну или сделать статически функции и тогда будет чтото вроде:

$tree = TreeModel::select("test", …)

Quote

to creocoder

и не вам рассказывать рационально что-то любить или нет. моё видинье я описал, с нестед сетс работал долго и делаю из этого соотвественные выводы. так что ненадо тут с пеной у рта рассказать что кому писать, не нравится моё виденье - игнорируйте мои посты. дальше вступать в дискуссию не намерен.

Что за неадекватная реакция? Вам с пеной у рта никто ничего не доказывает. Просто нужно называть вещи своими именами. Человек спросил, как в рамках Yii грамотнее всего реализовать Nested Sets, а вы ему какое то частное решение в виде GiST предлагаете, которое к тому же только под Postgre, да и Materialized Path. Я ничего не имею против данного алгоритма, но как я сказал выше, все алгоритмы имеют свои преимущества при решении тех или иных задач. И отдавать предпочтение какому либо из них без знания четкой задачи, либо навязывать его без обоснований - это создавать стереотипы у человека и пускать его по заведомо провальному пути.

demetrius

Что касается вашего вопроса. Самое грамотное решение задачи, если следовать идеологии этого замечательного фреймворка, это создание дочернего класса расширяющего CActiveRecordbehavior, либо CModelbehavior. Эти классы представляют собой так называемые “примеси”(mixins), которые позволяют в свою очередь обойти проблему множественного наследования в PHP. В итоге имея такой класс по работе в деревом мы можем его определить в методе behaviors() и наша модель получит все методы для работы с деревом в любой поддерживаемой Yii базе данных(MySQL, Postgre и т.д.). Это и будет самое оптимальное и грамотное решение.

ХМ. спасибо. вот это уже по делу.

когда сделаю, В ГуглГруппе выложу исходники кому интересно.  8) 8) 8) , если раньшеменя qiang ;D ;D ;D это не сделает во фреймворке

to demetrius

Смысла особого наверное нет, сейчас уточнил планы qiang, это будет в следующем релизе 1.0.5, который предположительно будет в самом начале мая. В принципе, как и предполагалось, ориентировка будет на CakePHP Tree behavior.