с механизмом я вроде бы определился, и окончательный выбор меня на самом деле немало удивил.
попробую обобщить здесь накопившуюся инфу о проведённых тестах.
чтоб не было потом лишнего пиздежа:
<disclaimer>
все нижеприведённые тесты некорректны априори!
сравнивались разные механизмы на двух совершенно разных СУБД, которые несравнимы.
единственное, что совпадало -- набор данных и структура дерева.
так или иначе, тесты я делал для себя, нужную мне информацию я получил, а всё остальное -- фпесду и ниибёт.
если появятся злоебучие крохоборы и борцы за Вселенскую Правду™, буду говорить лишь: "OMG STFU, don't bitch and get a life, dork!"
</disclaimer>
целью данных тестов было найти подходящий механизм хранения и обработки информации, структурированной в виде дерева, в СУБД PostgreSQL. механизм должен работать приемлемо быстро (кто как хочет, так и интерпретирует это определение) на деревьях в несколько тысяч нод, а также должен быть достаточно удобным на момент изменения содержимого дерева.
ладно, прежде всего -- общая картина -- графики с результатами. помимо обычного, привожу график с логарифмической шкалой, чтобы лучше была видна разница:

| INSERT | PATH |
| DESCENDANTS | DELETE |
INSERT - вставить необходимое кол-во нод в дерево.
набор данных и структура генерируются случайным образом однажды в самом начале тестов. поле "полезной нагрузки" в отдельной таблице лишь одно и содержит текст "node<N>", где <N> -- порядковый номер ноды.
PATH - для каждой ноды дерева получить её "путь" до корня дерева.
DESCENDANTS - для каждой ноды первого уровня получить всех её потомков.
DELETE - последовательно удалять каждую ноду первого уровня вместе со всеми её потомками.
вот теперь -- самое вкусное: описания графиков различных механизмов. хотя, описанием это назвать будет трудно, поэтому наверное лучше таки использовать термин обоснование.
гы, будет смешно, если потом окажется, что в тестах были грубые ошибки, и придётся точно так же всё обосновывать на противоположное. =)
ADJ-M - Adjacency List (MySQL)
несомненно, самый быстрый механизм.
на операции INSERT он просто таки уделывает всех конкурентов, т.к. мы тупо загоняем записи в дерево, лишь указывая каждой записи её прямого предка.
в таблице структуры обновляется лишь индекс по предкам.
на операции PATH уже даёт себя знать геморрой в коде, т.к. для каждого уровня мы должны сделать отдельный запрос:
SELECT nod_id FROM tree WHERE nod_id = ?nod_parentи тем не менее, разница по PATH с другими механизмами на MySQL исчезающе мала!
всё это потому, что MySQL прямо таки резок как понос на простейших выборках по PRIMARY KEY и сделает на них любую другую "взрослую" СУБД.
операция DESCENDANTS, которую можно в некотором роде считать обратной операции PATH, тоже наблюдается охуенная скорострельность, даже несмотря на рекурсию, к которой приходится прибегать. хотя, сознаюсь, у меня в тесте был лишь один цикл, а не рекурсия, что наверное децл ускорило выборку. так или иначе, эта операция совершенно не выбивается из ряда других механизмов на MySQL.
на DELETE все остальные немножко обосрались по сравнению с ADJ-M, даже несмотря на то, что удаление шло в две стадии -- точно так же, как и выборка в DESCENDANTS -- сначала получить список нод, а потом уже их удалить.
NST-M - Nested Sets (MySQL)
очень хороший механизм! прямо таки самый-самый, если не брать во внимание жутчайшие тормоза на операции INSERT, где время работы растёт экспоненциально.
INSERT: пиздец-какие-тормоза! ноу комментс.
PATH: супер быстро. быстрее работает только RAL-M, потому что там запросы проще.
DESCENDANTS: круче нас тока йайца! выборка по уникальному индексу -- что может быть быстрее.
DELETE: то же, что и в DESCENDANTS -- очень даже хорошо
RAL-M - Redundant Adjacency List (MySQL)
механизм такой же, как и ADJ-M, только в таблице со структурой дерева храним ссылки не только на прямого потомка ноды, но и на всех её потомков.
хороший механизм, и работает даже быстро. графики комментить не буду, но лишь замечу, что на тестах с большим кол-вом нод в дереве под PostgreSQL он получается просто пиздец каким избыточным, давая сильнейшие тормоза.
ADJ-P - Adjacecncy List (PgSQL)
да-да, я там наебался маленько в агенде к графикам. то, что обозначено RAL-P следует читать как ADJ-P (потом может быть поменяю, сейчас не могу). почему я отказался от RAL-P я уже пояснил в предыдущем параграфе.
итак, переходим на другую платформу -- PostgreSQL, для которой всё и делается.
теперь в БД я усиленно использую хранимые процедуры и триггеры, ессно постоянно думая о скорости работы, но и давая себе отчёт в том, что все эти фишки так или иначе будут тормознее, чем голый
важно: дефолтный конфиг PostgreSQL я поменял, выдав ему то ли 64М, то ли 128М памяти для работы. то, что ему даётся по умолчанию -- просто смешно.
ADJ-P показал себя на самом деле просто суперски.
INSERT: линейный рост и скорость сравнима с ADJ-M, хотя на каждое добавление ноды идёт один лишний SELECT (получить кол-во существующих детей у родителя) и UPDATE (инкремент счётчика детей для родителя). это делается потому, что SELECT COUNT(*) в PostgreSQL сканирует всю таблицу (сравнить с MySQL, где эти данные берутся напрямую из дескриптора таблицы), поэтому получается дешевле поддерживать этот счётчик во время работы, чем пересчитывать его каждый раз по мере надобности.
PATH: да, пришлось реализовать рекурсию на процедуре, и выборка пути теперь производится красиво:
SELECT nod_id FROM path_of(?nod_parent)...но даже вместе с этим, по скорости мы несильно выбиваемся из ряда графиков, полученных на быстром MySQL.
DESCENDANTS: тормоза-тормоза! но зато хоть рост практически линейный, да и выборка идёт с помощью рекурсии в хранимой процедуре, как это сделано в PATH, что очень и очень удобно для клиентского кода.
DELETE: в клиентском коде опять сплошные удобства -- удаляем только одну запись, а об остальном позаботится FOREIGN KEY. небыстро, но всё ж лучше, чем...
INT-P Nested Intervals
да, у меня получилось таки имплементировать Вложенные Интервалы. ну и поеботень же!
теория красива донельзя: смесь Nested Sets и Redundant Adjacency List, всё хранится в двух целых числах.
проблемы вылазят лишь на момент жёсткого использования механизма.
прежде всего, ограничение на кол-во нод в дереве. числа растут неприемлемо быстро, и обычного INT'а начинает нехватать, а переход на BIGINT, боюсь, ещё более затормозит, да и всё равно проблемы это не решит.
к тому же выборки потомков и предков производятся либо по функции с двумя умножениями и одним вычитанием (что жутко грузит процессор и дико тормозит), либо по числам с плавающей точкой (что не гарантирует точность).
результаты теста привёл для истории, но комментировать эту порнографию, везде возрастающую экспоненциально, совершенно не хочется.
в заключение только скажу, что я выбрал ADJ-P, т.к. всё остальное либо неудобно, либо тормозит. добавлю ещё пару хранимых процедур, чтобы максимально облегчить себе работу с кодом на стороне клиента, и будет мне щасье.
November 22 2004, 01:41:20 UTC 7 years ago
November 22 2004, 01:43:35 UTC 7 years ago
хранимые процедуры, триггеры, FOREIGN KEYS...
причём, PgSQL уже находится в своей 8-ой версии и все эти фишки там существуют давно, а значит всё уже хорошо отлажено и just works.
November 22 2004, 01:54:15 UTC 7 years ago
November 22 2004, 02:01:14 UTC 7 years ago
November 22 2004, 02:04:50 UTC 7 years ago
bopm.maloletka.ru
Нет, под пхп. Вики я забросил в начальной стадии. Потому как нет компаньонов по скорбному делу, да и сама концепция не совсем вставляет. Вики в моем понимании дополнительный инструмент, а не основной.November 22 2004, 02:07:30 UTC 7 years ago
Re: bopm.maloletka.ru
Вроде был же порт под mono, где-то на dev.udaff.com?November 22 2004, 02:09:19 UTC 7 years ago
Re: bopm.maloletka.ru
Тебе показалось. В текущий момент есть только планы по intercommunion.info.November 22 2004, 02:13:11 UTC 7 years ago
Re: bopm.maloletka.ru
А, вот почему мне так показалось, узрел в твоём wiki (http://bopm.maloletka.ru/GoMono?v=18icNovember 22 2004, 02:14:32 UTC 7 years ago
Re: bopm.maloletka.ru
Полная ссылка несколько другая =) Моя ошибка. Да и потом, с тех пор многое изменилось.November 22 2004, 02:18:37 UTC 7 years ago
Re: bopm.maloletka.ru
intercommunion.info -- что это? =)November 22 2004, 02:19:53 UTC 7 years ago
Re: bopm.maloletka.ru
Увидишь. Пока оно только хидеры отдает =)November 22 2004, 02:25:48 UTC 7 years ago
Re: bopm.maloletka.ru
Ок. Запиши меня в intercommunion.info Development Test Command. =)Anonymous
April 28 2007, 14:44:34 UTC 5 years ago
Re: bopm.maloletka.ru
интересноNovember 22 2004, 02:10:26 UTC 7 years ago
November 22 2004, 02:11:53 UTC 7 years ago
November 22 2004, 02:13:47 UTC 7 years ago
November 22 2004, 02:14:56 UTC 7 years ago
это у меня. испанский =)
но эт только в офисе. дома -- английский.
Anonymous
November 25 2004, 01:12:52 UTC 7 years ago
вопрос главный что в дереве
а ты об этом умолчал скромно :-)
вставки-удаления, это все не имеет смысла само по себе
а что если мы вставляем раз в год?
не удалем вообще?
классические проблемы типа тех что описывает целко -- суммы по чайлдам
или какие другие
это должно выбор определять :-)
November 25 2004, 01:18:42 UTC 7 years ago
"если мы вставляем раз в год" не канает. вставки будут довольно часто случаться, что сразу же перечёркивает Вложенные Множества на объёмах, больших нескольких тысяч нод (это очень мало).
"не удаляем вообще" -- оно конечно правильно с точки зрения теории баз данных, но мы живём в реальном мире, и всякую хрень приходится за собой подчищать периодически =)
в данном случае я выбираю механизм по производительности и удобству работы с ним из клиентского кода на РНР. ADJ-P мне показался (и до сих пор кажется) оптимальным.
Anonymous
November 25 2004, 01:23:49 UTC 7 years ago
но таки ты не сказал *что* это будет :-)
ибо возможнны варианты
например мы использовали еще всякие комбинированные схемы
типа nested sets к которым листья крепятся как AL
btw ты не хочешь выложить серверный код?
sp etc
может соптимизируем чего
November 25 2004, 01:33:27 UTC 7 years ago
статистику посещений в риал-тайме туда ессно никто пихать не будет, также как и форумы на сотни тыщ постов, но какой-нибудь "сайтик" на несколько тысяч страниц/документов/товаров должно будет держать не напрягаясь, иначе жоппа. =)
в серверном коде на самом деле ничего такого нет. обычная реализация Adjacency List с рекурсией. вечерком, как приду домой, вытащу что есть и выложу в новом посте.
Anonymous
November 25 2004, 01:32:35 UTC 7 years ago
> линейный рост и скорость сравнима с ADJ-M, хотя на каждое добавление ноды идёт один лишний SELECT (получить кол-во существующих детей у родителя)
как делал это? :-)
November 25 2004, 01:34:29 UTC 7 years ago
под Постгресом оно так индексы юзает в отличие от SELECT COUNT(*) ...
December 2 2004, 07:19:43 UTC 7 years ago
Где можно почитать об алогритмах?
December 2 2004, 07:31:19 UTC 7 years ago
все названия даны, разве что только обозначение RAL -- моя собственная выдумка, но там всё и так ясно и понятно.