Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.08.2005, 13:05 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. 2. 3. 4. 5. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.08.2005, 14:23 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
я с процедурами постгреса знаком понаслышке, но ИМХО - это очень мало. Могу посоветовать запостить это в http://www.livejournal.com/userinfo.bml?user=ru_pgsql http://www.livejournal.com/userinfo.bml?user=ru_php http://www.livejournal.com/userinfo.bml?user=ru_webdev эти сообщества читают некоторые люди, интересующиейся nested sets ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.08.2005, 18:35 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. 2. 3. 4. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.08.2005, 19:02 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.08.2005, 19:43 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
авторПосмотрев на это пришел к выводу, что для вставки и перемещения требуются два дополнительных параметра, которые помогут более точно задать точку назначения. Я назвал их X и Y они оба логические (2 во второй степени = 4 хихи). Все очень интересно, но не могли бы Вы пояснить (хотя бы на пальцах) смысл введенных логических переменных? Что значит "более точно задать точку назначения"? Это оптимизирует поиск узла? Похоже, вложенные множества сильно оптимизируют скорость выборки из дерева, однако как зависит скорость вставки и удаления от числа узлов дерева? Эта зависимость сильно хуже линейной? Еще один вопрос: могут ли быть пробелы в нумерации левых и правых ключей или это принципиальное условие? P.S. Простите за обилие вопросов, это не со зла :) Мне действительно интересна эта тема. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.08.2005, 16:43 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. Все очень интересно, но не могли бы Вы пояснить (хотя бы на пальцах) смысл введенных логических переменных? Что значит "более точно задать точку назначения"? Это оптимизирует поиск узла? Они не улучшают время выполнения. Они облегчают жизнь. Исходное дерево: Корень Птицы Звери Лев Растения Вставка (Звери, X = 0, Y = 0) - _до_ Зверей на _том_же_уровне_ Корень Птицы НОВЫЙ Звери Лев Растения Вставка (Звери, X = 0, Y = 1) - _до_ _дочерних_ элементов Зверей Корень Птицы Звери НОВЫЙ Лев Растения Вставка (Звери, X = 1, Y = 0) - _после_ Зверей на _том_же_уровне_ Корень Птицы Звери Лев НОВЫЙ Растения Вставка (Звери, X = 1, Y = 1) - _после_ _дочерних_ элементов Зверей Корень Птицы Звери Лев Новый Растения Видите зависимость между значениями X,Y и подчеркнутыми фразами? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.08.2005, 18:39 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
nostromo Похоже, вложенные множества сильно оптимизируют скорость выборки из дерева, однако как зависит скорость вставки и удаления от числа узлов дерева? Эта зависимость сильно хуже линейной? Насчет скорости обновления все надо проверять. Точных данных пока не могу сообщить. nostromo Еще один вопрос: могут ли быть пробелы в нумерации левых и правых ключей или это принципиальное условие? Мой вариант не допускает пробелов по идее ;) Пробелы мешают быстро считать кол-во дочерних элементов вот таким запросом: Код: plaintext В результате этого запроса вы получите кол-во детей для каждого узла. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.08.2005, 18:41 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
Спасибо. Функционально назначение переменных X и Y понятно. Однако, с точки зрения употредления деревьев понятие "естественного порядка дочерних элементов", как правило, не важно. Например, вложенные файлы и папки мы сортируем каким-то внешним условием: по именам в алфавитном порядке, по дате и т.д. В редких случаях можно признать полезность естественного порядка, но его всегда можно реализовать как дополнительное поле узла дерева. Вопрос про эффективность Вашего решения я задал потому, что много слышал о соответствующих проблемах реализации иерархических структур поверх реляционных БД. Вопрос о пробелах в нумерации ключей для обхода связан с этим же: с ростом дерева расходы на обновление ключей при вставке и удалении узлов очевидно будут расти. Если разрешить пробелы в нумерации, то, как мне кажется, можно будет большинство вставок и удалений узлов без обшироных обновлений ключей. Когда-то давно строки программы на Бейсике нумеровались числами, кратными 10, чтобы удобнее было вставлять новые в случае необходимости. Теперь по-поводу легкого подсчета количества дочерних элементов. Судить о том, что важнее -- эффективность модификаций дерева или легкость подсчета числа его элементов можно, на мой взгляд только исходя из конкретики прикладной задачи и результатов контрольных тестов на данных, близких к реальным. Можно конечно придумывать лекарство, а потом искать болезнь, но в такой сугубо прикладной области, как базы данных, как мне кажется, более естественен обратный путь. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.08.2005, 19:34 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
Nostromo, если честно, не хочется полемизировать. Данное решение было сделанно мной под конкретную задачу, такая задача стоит перед многими. В моем случае это создание удобной навигации по веб-каталагу с несколькими тысячами позиций. Очень хочется добавить, что на мой взгляд иерархии в виду сложности представления в реляционном виде подходят только для определенного круга задачь. Решения данных задач зависят от средств реализации. Мне крайне сложно представить задачу в которой будет применяться ЧАСТО обновляемая иерархия, в таком случае ее просто не стоит использовать помоему. Возьмите к примеру веб-сайт, у которого несколько десятков тысяч уникальных хостов в сутки, и несколько сотен тысяч хитов, как вы себе представляете более частное использование вставки и обновления чем выборки в данном случае, эти величины просто несопоставимы, т.к. разница в несколько порядков минимум. Насчет бейсика и пропусков. Можно придумать огромное кол-во фишечек, например ввести такое понятие как номер дерева, если у вас их несколько, ну и мало ли что еще. Но все это частные решения, которые мне в данном случае не интерестны, я хотел бы обсудить КОНКРЕТНОЕ решение САМОЙ идеи, без. Этот топик был содан для того чтобы мне специалисты по постгресу помогли доработать мои недостатки, и для того чтобы у людей была конкретно реализованная идея, которую можно переработать под себя, согласитесь это совсем несложно было бы сделать. P.S> Я не хотел бы счас спорить о целесообразности или наоборот данного решения. Я хотел бы найти ошибки и исправить их, оставив качественно проработанный результат, для дальнейшего использования. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2005, 10:39 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
Paul Chabinsky, вы смотрели имеющиеся решения? http://sql.ru/forum/actualthread.aspx?tid=202006#1725807 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2005, 11:30 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
Paul Chabinsky P.S> Я не хотел бы счас спорить о целесообразности или наоборот данного решения. Я хотел бы найти ошибки и исправить их, оставив качественно проработанный результат, для дальнейшего использования. гм. Решение представления дерева в виде хранения номеров правых и левых узлов не ваше. Т.о. обсуждать его тут незачем. (Если не обсуждать его эффективность с т.з конкретных применений, чего вы не хотите). Вы хотите чтобы тут вылавливали ваших блошек? Кому это надо? Я себе реализовал другое решение (из за того, что моя задача - это интенсивно растущее _преимущественно_ вверх (т.е. с _редкой_ пересадкой ветвей) дерево. При этом Ваше "право/левое" решение в среднем будет двигать полдерева (обновлять номера соседних узлов) - что затратно. Очевидно, что хранение только родительского узла наиболее дешево по вставке, но видимо далеко не дешево по поиску иерархического подчинения (через вызов рекурсивной ф-ии). Но, насколько я помню, и "ваше" решение сводит к _агрегатам_ относительно частые задачи поиска (т.е. медленно, или я не прав?). Могу обсуждать преимущества моего решения против вашего, но ни ловить ваши ошибки реализации, ни предлагать для ловли блошек (того же рода) свои не собираюсь. ЗЫ. Кстати сказать, к постгресу есть и _патчик_, который позволяет создавать рекурсивные запросы к деревьям. Где-то тут пробегали люди, его применявшие. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2005, 11:44 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2005, 11:59 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
2 LeXa NalBat Видел ссылку что вы предложили. Но ничего конкретного для себя в ней не нашел к сожалению. 2 4321 1) Я нивкоем случае не претендую на то что я придумал как хранить дерево. И я да же не претендую на то что придумал как им управлять, я просто сделал аккуратную и лаконичную на мой взгляд реализацию. Которую хотел обсудить. 2) Joe Celko (его я считаю автором данного алгоритма) написал книжку про деревья в базе, я ее к сожалению не видил. Но в интернете именно от его имени не встречается ниодной реализации управления таким деревом, единственное что я нашел это процедура которая из id и parent_id, расчитывает поля left и right всего дерева. 3) Про агрегаты не понял к сожалению. Но насчет поиска могу только привести пример выборки дочерних узлов ноды: Код: plaintext 4) Насчет коннект бай, это та же самая рекурсия... просто враппер для того чтоб вам не писать рекурсивную функцию самому вручную. 2 glebofff Спасибо за ссылку, ее я то же видил, до того как сделал выложенный тут вариант. Мне просто данный вариант кажется несколько несистематезированным. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2005, 12:36 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
Paul Chabinskyпривести пример выборки дочерних узлов ноды: Код: plaintext кааца я вспомнил (поправьте если совру): - тут у вас AND level > parent_level - лишнее (для правильного обхода по дереву левел есть ф-я лефт и райт) и кажется само хранение левела - избыточно, а левел как раз и считается при помощи каунтов по неким запросам для "минимально избыточного" древа, хранящего только лефт и райт. _ зы: я не работал с рекурсией. А именно со вспомогательной индексированной таблицей "полной структуры" дерева (все ссылки с узла на всех его предков по иерархии, без указания левела). Оценочно (число записей в такой структуре) <= (число записей в дереве)*(глубина дерева). Структура может строиться по иерархическому дереву в любой момент, но у меня строится триггерами синхронно. Количество вставляемых/удаляемых в структуру записей при вставке/удалении узла в конец/из конца ветки <=(глубина дерева) - как правило это много меньше половины узлов дерева - как в вашем случае; при перемещении/удалении целых ветвей естественно затрагивается гораздо больший пласт записей, ну дык это и более редкая операция. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2005, 12:51 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
2 4321 Да действительно поля parent_id и level избыточны, но значительно упрощают работу. Если они не нужны можно легко удалить их обработку. С вашим методом я знаком, пробовал его, очень хароший метод, но мне он не подходит. Обсудить я хотел бы именно Nested Set, и конкретную реализацию (устал повторять). P.S> Вообще прихожу к выводу что я зря все это затеял. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2005, 13:17 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
Paul Chabinsky2 4321 Да действительно поля parent_id и level избыточны, но значительно упрощают работу. Если они не нужны можно легко удалить их обработку. С вашим методом я знаком, пробовал его, очень хароший метод, но мне он не подходит. ну вот и хотелось бы узнать, по каким именно причинам (тот или иной) метод может не подходить. (кстати, в некоей модификации я храню в такой структуре не одно дерево, а лес, с множеством корней не имеющими предков (Null) - вроде бы неплохо работает. Петли запрещает автоматом. Вот думаю, нельзя ли отмодифицировать под множественное наследование - т.е. под граф). Paul ChabinskyОбсудить я хотел бы именно Nested Set, и конкретную реализацию (устал повторять). P.S> Вообще прихожу к выводу что я зря все это затеял. ничего странного. Если найдется еще реализатор/пользователь _именно_ Nested Set, он видимо и поковыряется именно в _реализации_. Не расстраивайтесь. Я долго зарился на NS, но число узлов >> 10 000, знаете ли. Стоимость апдейта в среднем >>5000 записей _самого_ дерева на каждую операцию вставки не вдохновляла. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2005, 13:28 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
To 4321: 4321зы: я не работал с рекурсией. А именно со вспомогательной индексированной таблицей "полной структуры" дерева (все ссылки с узла на всех его предков по иерархии, без указания левела). Оценочно (число записей в такой структуре) <= (число записей в дереве)*(глубина дерева). Структура может строиться по иерархическому дереву в любой момент, но у меня строится триггерами синхронно. Если я правильно понял, то "индексированной таблицей "полной структуры"" -- это таблица, каждая запись которого соответствует ребру графа, если рассматривать дерево как граф. Если корень только 1, то количество ребер в точности равно N-1, где N -- количество количество узлов дерева (есть такая теорема). Если граф состоит из M деревьев и имеет N вершин, то соответственно в нем будет ровно N-M ребер. По поводу хранения идеи реализации произвольного графа. Все задачи, связанные с графами можно разделить на два класса: 1) задачи, в которых узлы представляют достаточно сложные прикладные объекты. В этом случае граф имеет вспомогательную роль и его можно рассматривать как один из индексов для поиска; 2) задачи, в которых важна именно структура графа. В первую очередь, к ним относятся классические сетевые задачи из методов оптимизации (алгоритм Форда-Фолкерсона, алгоритм Краскала, поиск подграфов специального вида и т.д.). Насколько я знаю, для задач второго сорта наиболее эффективными структурами представления графа являются матрица смежности и матрица инцедентности, т.е. БД имеет смысл использовать только для больших графов, да и то для хранения именно таких структур. В задачах первого сорта, по моим наблюдениям, графы сложнее деревьев встречаются редко (могу только векторные редакторы вспомнить). Впрочем, это лишь некоторое мое замечание, ничего против идеи я не имею. To Paul Chabinsky: Paul ChabinskyВозьмите к примеру веб-сайт, у которого несколько десятков тысяч уникальных хостов в сутки, и несколько сотен тысяч хитов, как вы себе представляете более частное использование вставки и обновления чем выборки в данном случае, эти величины просто несопоставимы, т.к. разница в несколько порядков минимум. Не может ли случиться, что наилучшим решением в этом случае будет являться использование встроенного btree индекса, который, как я понимаю, и есть дерево для поиска, реализованное на низком уровне? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2005, 17:57 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
блин, авторизовался, писал подробный ответ, старался высунув язык, как идиот, а этот долбанный сайт сожрал всё, выдал отлуп (куку он поселя, видимо) и не поперхнулся ... сцука короче вы ,nostromo, несолько неправы. Что такое вспомогательная структура - см по ссылке автора в посте '1825061'. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2005, 18:26 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
To 4321: Да, просмотрел я эту ссылку, теперь понятно. Впрочем, теперь можно сделать новые оценки (ну математик я по профессии :)). Если имеем сбалансированное дерево c L уровнями, у которого каждый узел имеет k предков, то количество узлов (записей в первой таблице) будет равно: (k^L-1)/(k-1), а количество записей во второй, вспомогательной таблице: ((L-1)*k^(L+1) - L*k^L + k) / (k-1)^2. Сама идея с двумя таблицами мне понравилась, может пригодиться. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2005, 19:14 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
Меня спрашивали насчет произоводительности. Компутер: Ноутбук, 1.3Мц, 512мб. Я сделал дерево на 6к элементов (это конечно оч мало, но меня устраивает). Корневой элемент содержить 10-ть дочерних (нулевой уровень), Элементы первого еще по 10-ть Элементы второго еще по 10-ть Эдлементы третьего по 5-ть. Создание такова дерева заняло 110 секунд (скриптом на PHP). Не спрашивайте как получилось 6к Так вот вставка узла в середину (как дочерний для среднего элемента четвертого уровня) дерева : 200-220мс Вставка узла в начало первого уровня 400-500 мс. Перемещение среднего узла с его потомками в начало первого уровня (хотя я мож че попутал) : 10мс. Меня такие результаты устраивают. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.08.2005, 10:31 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
nostromo(ну математик я по профессии :)).Внушает! nostromoЕсли имеем сбалансированное дерево c L уровнями, у которого каждый узел имеет k предков, то количество узлов (записей в первой таблице) будет равно: (k^L-1)/(k-1), а количество записей во второй, вспомогательной таблице: ((L-1)*k^(L+1) - L*k^L + k) / (k-1)^2.долго думал. но раз есть что-то про "балананец" подумал, что речь таки о потомках, а не о предках. (каждый узел имеет не более 1 прямого предка и не более L иерархических), причем даже для случая "потомков" надо подправить формулировку -"каждый узел, за исключением терминальных... " ( имеет ). (кстати, а к какому типу девиаций относится имение предков, а к какому - потомков?) Но вообще-то говоря интересны именно деревья (и графы) количество потомков у узла которых заведомо не фиксировано, и более того, зависит от узла (некие классификаторы сущностей с перестраиваемой классификацией). Т.ч. в чести более мягкие ограничения и более мягкие оценки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.08.2005, 10:34 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
Да, конечно, в моем последнем посте есть ошибки, должно быть так: Если имеем сбалансированное дерево c L уровнями (полностью заполненными) , у которого каждый узел, кроме терминальных (не имеющих потомков) имеет k потомков , то количество узлов (записей в первой таблице) будет равно: (k^L-1)/(k-1), а количество записей во второй, вспомогательной таблице: ((L-1)*k^(L+1) - L*k^L + k) / (k-1)^2. Применять это можно, например, следующим образом. Предположим, что количество потомков у произвольного узла в среднем равно k (независимо от уровня), тогда среднее количество записей вспомогательной таблицы, необходимых для обслуживания этого дерева, будет определять указанным выше значением. Далее, предположим, что L фиксировано, а k равстет, тогда количество вспомогательных записей эквивалентно L*k^(L-1). Если рассматривать рост количества записей доп. таблицы (обозначим через M количество записей доп. таблицы) относительно количества узлов дерева (обозначим через N), то получим оценку: M/N эквивалентно L-1 (при больших k). Т.о., для дерева с четырьмя уровнями иерархии, L=4 (на первом уровне находится только корневой узел), у которого каждый узел (кроме терминальных) имеет в среднем 10 потомков, можно ожидать, что количество строк доп. таблицы будет в 3 раза превышать количество узлов (в этом случае количество узлов N = 1111 в среднем). В случае, когда k фиксировано, а L растет имеем: M/N эквивалентно (L-1)*k/(k-1). Замечу, что эти оценки асимптотические (т.е. понятие больших значений не конкретизируется), и справедливы в среднем для всех деревьев с указанными ограничениями. Аналогично можно рассмотреть случай, когда среднее количество потомков узла зависит от увовня (и эта зависимость известна), а также случай, когда имеется не одно дерево, а лес. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.08.2005, 15:51 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
Предлагаю сравнить подходы с Nested Sets (NS) и доп. таблицей (ДТ) by 4321. То, что приведено ниже, только мое мнение, на котором я сильно не настаиваю! Типичные задачи: 1. получить всех предков определенного элемента. NS - скорость пропорциональна глубине (необходим рекурсивный поиск, поле level помогает слабо) ДТ - быстрый запрос по доп. таблице 2. получить всех потомков определенного элемента. NS - быстрый запрос ДТ - быстрый запрос по доп. таблице 3. получить количество потомков данного элемента NS - мгновенно ДТ - быстрый запрос по доп. таблице 3. получить непосредственных потомков данного элемента одинаково быстрый запрос для обоих подходов 4. получить информацию об уровне заданного элемента NS - мгновенно ДТ - быстрый запрос по доп. таблице (считаем предков) 5. проверка терминальности элемента одинаково быстрый запрос для обоих подходов 6. поиск всех элементов заданного уровня NS - быстрый запрос ДТ - довольно тяжелый запрос (рекурсивный поиск от корня) Особенности NS: - сравнимельно маленькая избыточность данных - поддержка и управление линейной упорядоченности непосредственных потомков - довольно тяжелые обновления при модификации дерева. Особенности ДТ: - легкая модификация дерева - приличная избыточность данных (вся доп. таблица) - при слишком больших размерах доп. таблицы, количество записей в которой больше числа узлов, "быстрые" запросы могут оказаться не такими уж и быстрыми ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.08.2005, 15:51 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
анализ (в части "рекурсий") не совсем верен: к 1. если я правильно помню, то никаких рекурсий в НС не нужно, хвататет групповых запросов с агрегированием. Сейчас вспоминать не хочу, что именно нужно для 1. но можно поискать ссылки по н.с. то же самое к 6. t_parents - доп таблица автор Код: plaintext 1. 2. 3. Время получения данных:109 ms. получено строк: 2996 на большем объеме данных Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.08.2005, 16:30 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
- приличная избыточность данных (вся доп. таблица)- ее б скажем не хранить, а стартовать в общую "переменную" табличного вида (обобщенную между коннектами времянку) при первом запросе к базе любого коннекта, и нехай себе висит (и перестраивается) только в памяти (размер то записи невелик). Может быть есть что-то в этом ключе? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.08.2005, 16:44 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
1. получить всех предков определенного элемента. Код: plaintext ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.08.2005, 16:49 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
Paul Chabinsky1. получить всех предков определенного элемента. Код: plaintext Да, кстати: Код: plaintext 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.08.2005, 17:03 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
Кажется, если таблица в памяти мало места занимает, то на диске и подавно :) Замечу, что в постгресе каждая строка таблицы сопровождается заголовком приличного размера, частенько превышающего размер пользовательских данных: из документацииAll table rows are structured in the same way. There is a fixed-size header (occupying 27 bytes on most machines), followed by an optional null bitmap, an optional object ID field, and the user data. The header is detailed in Table 49-4. The actual user data (columns of the row) begins at the offset indicated by t_hoff, which must always be a multiple of the MAXALIGN distance for the platform... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.08.2005, 17:04 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
nostromoКажется, если таблица в памяти мало места занимает, то на диске и подавно :)смысел не в месте в памяти, а в соотношениии цен дисковых операций к операциям в памяти. ( т.е. чисто физические 3-4 порядка -прим. для математиков именно этим кстати кажеца объяснялося модное стартование tempdb в память для мс-скуль 6.5 ) А поскольку все данные этой таблицы - исчисляемые, (изьыточные) - то и нет необходимости хранить их на диске (достаточно строить, но быстро и один раз, после старта) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.08.2005, 10:41 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
да, а по поводу хидеров - это кажеца повод хранить исчисляемую (избыточную, но необходимую для SQL выборок) иерархию в индексированных тестовых полях в виде .1.123.78987... - кол-во шапок на иерархию узла поджимаеца (даже если табличка иерархий будет отдельной от соб-сно дерева), правда апдейты пойдут с расщеплением поля, но, похоже, не сложным. (И еще - не потребуется ли обращенного индекса - т.е. (функционального?) индекса на обращенную строку?) Что вы об этом думаете? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.08.2005, 10:50 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
4321смысел не в месте в памяти, а в соотношениии цен дисковых операций к операциям в памяти. (т.е. чисто физические 3-4 порядка хорошо, согласен, однако такие оптимизации в проектах обычно проводятся в последнюю очередь, к тому же так можно что угодно ускорить, а не только Ваш алгоритм. 4321да, а по поводу хидеров - это кажеца повод хранить исчисляемую (избыточную, но необходимую для SQL выборок) иерархию в индексированных тестовых полях в виде .1.123.78987... - кол-во шапок на иерархию узла поджимаеца (даже если табличка иерархий будет отдельной от соб-сно дерева), правда апдейты пойдут с расщеплением поля, но, похоже, не сложным. Честно говоря, работать с индексированными полями не приходилось, не знаю насколько это быстро. Память, конечно, экономится, но потерять в скорости, как мне кажется, можно прилично. Например, перевод из текста в число операция не самая быстрая, да и лишняя, т.к. память экономится только для маленьких значений (которых меньшинство): 4-х байтовое целое занимает до 10 байтов в десятичной десятичной и до 8 в шестнадцатеричной. В общем, здесь лучше индексированные целые поля. 4321(И еще - не потребуется ли обращенного индекса - т.е. (функционального?) индекса на обращенную строку?) Это не понял, поясните. Если мыслить масштабно, то, кажется, идеальный вариант для любого алгоритма, оптимизирующего работу с некторой структурой -- это соответствующий встроенный в систему индекс плюс оптимизатор, умеющий его эффективно использовать. Может, пора связываться с разработчиками или писать свое расширение? :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.08.2005, 14:19 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
nostromo Например, перевод из текста в число операция не самая быстрая ну в случае хранения иерархий в поле (hierarchy text;) запросы на вхождение будут иметь (скажем) вид WHERE c.hierarchy LIKE t.hierarchy||'.*' т.ч. преобразование типов тут не нужно. (оно потребуется только при заполнении hierarchy триггером - из числа в текст) nostromo т.к. память экономится только для маленьких значений (которых меньшинство): 4-х байтовое целое занимает до 10 байтов в десятичной десятичной и до 8 в шестнадцатеричной. речь шла о экономии на шапках записей - но кажется вы о том, что потери из-за преобразования в строку их съедят? nostromo 4321(И еще - не потребуется ли ... индекса на обращенную строку?) Это не понял, поясните.мои извинения, - это ложный перенос идеи о 2-х индексах (pid,id)|(id,pid) (что удобно для поиска как предков так и потомков) на случай текстовой иерархии. Кажется индекс на обращенную строку не пригодится - предки ищутся так же как и потомки только таблицы меняются в LIKE местами. _______ ЗЗЫ: nostromoЕсли мыслить масштабно, то, кажется, идеальный вариант для любого алгоритма, оптимизирующего работу с некторой структурой -- это соответствующий встроенный в систему индекс плюс оптимизатор, умеющий его эффективно использовать. Может, пора связываться с разработчиками или писать свое расширение? :)а я вот не думаю, что тут пора "мыслить масштабно". Ибо... Ибо обнаружил, что идея спотыкается на том, что при апдейте (пересадке веток) приходится прибегать к использованию конструкций вида DELETE ... WHERE t.field IN(SELECT f FROM ....) (или (t.f1,t.f2) IN( SELECT f1,f2 FROM....) , а они даже для случая отсутствия зависимости сабселекта от полей внешних (к сабселекту) считаются неоптимально - а именно сабселект считается для каждой записи (я даже пытался подоткнуть туда STABLE ф-ю -думая обмануть природу - ан. фих). Т.ч. экономия метода частична - вставка веток - дело практически "бесплатное" (недорогое), но вот пересадка (даже терминалов, если не выделять их пересадку в отдельную ветку триггерного алгоритма) напрягает. я конечно нашел, что можно обмануть эту проблему (почти на порядок - полтора на ~100 000 записях в иерархичке) составлением стрингов для IN(,,,,), но это, мне кажеца, "не дело" - неужто оптимизатору так трудно выяснить отсутствие зависимости сабселекта от полей выбираемой в селекте записи? Вот уж что действительно давно пора бы было от"оптимизировать" разработчикам... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.08.2005, 15:25 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
4321 Paul Chabinsky1. получить всех предков определенного элемента. Код: plaintext 4321это кажеца повод хранить исчисляемую (избыточную, но необходимую для SQL выборок) иерархию в индексированных тестовых полях в виде .1.123.78987...Вроде бы так сделано в ltree. 4321DELETE ... WHERE t.field IN(SELECT f FROM ....)Можно заменить на exists ( select 1 from ... where f=t.field ). Или приджоинить: http://www.postgresql.org/docs/8.0/static/sql-delete.html#AEN41779 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.09.2005, 10:28 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
LeXa NalBat 4321DELETE ... WHERE t.field IN(SELECT f FROM ....)Можно заменить на exists ( select 1 from ... where f=t.field ). Или приджоинить: http://www.postgresql.org/docs/8.0/static/sql-delete.html#AEN41779Спасибо, посмотрю! ( Я как раз и хотел поругаца на отсутствие "ДИЛЕТА ... ФРОМ ДЖОНА" (як скажем в неких настольных вструментах типа аксеса). Тут, насколько я понял, омиттед фром в полной красе. Вот только дилет форм аутер джон так кажеца не реализуеца.) Что касаеца exists - пробовал в первую голову, получил времена на полпорядка _хуже_, чем при 2-х id IN(Select ...) AND pid IN(Select ...). Пока (из опробованного) наискорейшее - сшивать строку IN(,,,,,) и выполнять EXECUTE (при малом количесве подчиненных срабатывает раз в 10 -15 быстрее чем с IN(SELECT ...), но не совсем понятно, что будет при очень больших строках (есть ведь наверное и ограничения на длину SQL инструкции? Пока проверял - при перемещении веток с ~280 потомками по иерархии работает). Правда появилась идея (не сшивать строку) а напрямую делетить записи в plpgsql-ой ХП в цикле (в аксессе бы подобное в VBA делать не стал - заведомо плохо, но в plpgsql имеет смысл оттестировать для пробы). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.09.2005, 10:55 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
, сорри, не заметил: also it cannot handle self-joins. т.ч. джойн по омиттед фром нервенно курит у сторонке (мля) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.09.2005, 11:47 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
4321, сорри, не заметил: also it cannot handle self-joins. т.ч. джойн по омиттед фром нервенно курит у сторонке (мля)Фихвам! Абманём за счет вью! (голь на видумки хитра) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.09.2005, 11:49 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
2 LeXa NalBat к проблеме DELETE FROM ... WHERE IN(... ) на моих данных: к сожалению нагрузка на сервер непостоянна. Т.ч. тестовые результаты различаются иногда на порядки по временам (на одних и тех же данных). Поэтому числа не привожу. Но примерно такое резюме (при подмене функций в триггере обновления предка узла дерева): 1.EXECUTE (... IN (\' ||с_подстановкой_наборов||\' ) ~ на порядок лучше изначального дилета. 2. цикл DELETE внутри лупа - близко по скорости к дилету по 1. (на ~ 280*3 записей в лупе). (очень может быть, что скорости дилетов по пп. 1. и 2. разнятся сильнее - в триггере есть еще и инсерты, дающие примерно такой же вклад, но радует хотя бы то, что не надо думать о предельной длине SQL строки) 3. дилет с "ommited from" джойном в WHERE с 2 видами (той же таблицы) - раза в 2-3 похуже 1 и 2 4. Очень хотелося неявно заджойнится на SETOF ф-ю. Но, кажется этого нельзя. Т.е. нельзя ни заполнить сетоф переменную в plpgsql, ни написать функция($1).поле в WHERE. Можно видимо посмотреть в сторону времянки. Но времянки - это к сожалению не фонтан (дисковые операции). ЗЫ: надо бы потестить чистые дилеты на модельных данных, на незагруженном сервере. неушто придеца дома ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.09.2005, 14:21 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
43213. дилет с "ommited from" джойном в WHERE с 2 видами (той же таблицы) - раза в 2-3 похуже 1 и 2киньте пожалуйста explain ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.09.2005, 14:46 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
LeXa NalBat 43213. дилет с "ommited from" джойном в WHERE с 2 видами (той же таблицы) - раза в 2-3 похуже 1 и 2киньте пожалуйста explain как говорилося выше:(при подмене функций в триггере обновления предка узла дерева)где для случая джойна подставлялась: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.09.2005, 15:12 |
|
||
|
Готовое решение для работы с деревьями.
|
|||
|---|---|---|---|
|
#18+
А что если ветка переедет на другой парент или промежуточные паренты вставить или удалить... Потребуется обновление и переиндексация всех дочерних записей, а их в данной задаче в сотни раз больше чем парентов. Интересно, что получилось в результате? Насколько работоспособна эта база и в какой предметной области применяется? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.12.2007, 13:37 |
|
||
|
|

start [/forum/topic.php?all=1&fid=53&tid=2004773]: |
0ms |
get settings: |
9ms |
get forum list: |
12ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
47ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
60ms |
get tp. blocked users: |
1ms |
| others: | 257ms |
| total: | 401ms |

| 0 / 0 |
