"Tonal" wrote ...
24.06.2011 13:49, Khorsun Vlad пишет:
EB вполне устраивает.
Он не будет рекурсивным.
Этому есть какие-то причины теоретического плана или технического?
Нет конечно, это мой каприз.
Мне казалось, что ЕБ ничем от сохранёнки не отличаются кроме наличия
имени. Если это так, тогда невозможность рекурсии решается просто
введением ключевого слова или иного механизма позволяющего вызвать себя.
Видимо я ошибался. Но до сих пор не понимаю причину нежелания делать рекурсию в
ЕБ.
Возможно это как-то связано с мониторингом или другими подобными механизмами.
Поэтому и хочется узнать причины из первых рук.
Расскажи в общих чертах.
Да, ошибался. В общих чертах - EB сделан на уровне DSQL, который стоит "над"
движком, который выполняет запросы. Поэтому для самого движка нет такого
понятия,
как EB. И возможность рекурсивного вызова туда так просто не приделать.
Да, вобщем-то можно просто ввести опциональное имя для ЕБ.
Тогда нет нужды в каком-то дополнительном ключевом слове. :)
Не в имени дело.
По факту единственным универсальным инструментом для работы с деревьями
на сервере остаются рекурсивные сохранёнки. :(
Не вижу в этом ничего плохого. Ну и это утверждение ничем не доказано.
Вот я и пытаюсь это обосновать.
Что именно ? Что нет ничего плохого в процедурах ? :)
Про удаление мы вроде бы выяснили:
delete from ... where id in (with recursive...)
отвалится, если связь без каскадного удаления, т. к. невозможно задать
порядок удаления.
Нет, мы выяснили что есть for with recursive который позволяет не
писать процедуру (А ЧЕМ ПЛОХО ПИСАТЬ ПРОЦЕДУРУ ???)и обойтись без
несуществующего рекурсивного EB
Т. е. без применения PL-SQL не обойтись. Согласен.
EB это тоже PSQL, как ни странно. (Кстати PL\SQL - это из оракла, у нас PSQL)
Хотя на мой взгляд какой-то вариант delete был бы более ясныйм и простым
способом...
Ясность и простота - понятия часто субъективные...
Нельзя сделать поиск по путям.
Ты с кем разговариваешь ? Я тебя уже потерял :)
Это когда узел идентифицируется не его ID-ом а последовательностью
значений какого-то атрибута по уровням (как путь в файловой системе)
А в чём проблема ? И зачем для такой схемы рекурсия ?
Опять же, такой запрос как посчитать количество дочек для каждого узла в
указанной ветке будет отставать по скорости примерно на степень от
прямой рекурсивной реализации (как O(n) от O(n^2) или больше).
Опять бездоказательное утверждение. И опять не вижу причин отказываться
от процедур.
Для простейшего дерева выдать количество непосредственных детей
действительно проблем нет:
...
Но вот подсчитать количество всех детей у меня не вышло. :(
...
Кто предложит рабочий вариант подсчёта общего количества прямых и
непрямых детей для указанной ветки?
Дальше можно будет трудоёмкость посчитать. :)
Т.е. "O(n) от O(n^2) или больше" взято из пальца, как я и написал выше, так
? :)
На досуге подумаю над этим вопросом, но быстро не обещаю. Это тебе Таблоида
напрячь надо, он любит такие задачки решать :)
Так же нет возможности организовать копирование веток, их слияние - т.
е. модификацию дерева.
Опять без доказательства.
Тут у меня даже идеи нет с какой стороны подходить без явной рекурсии
или внешнего стека.
Может кто-нибудь предложит набросок идеи?
Выбираешь копируемую ветку, но меняешь в ней старые ID на новые и
вставляешь результат в дерево.
П. С. Ну а если бы механизм СТЕ развился, чтобы покрывать хотя бы часть
этих задач, было бы просто нереально круто! :)
А может ты просто не нашёл решения для части этих задач ?
Вот и спрашиваю, может ещё какие-то подходы есть которые я не увидел?
Наверняка. И не обязательно связанные с рекурсией и с CTE. Например, можно
вынести связи в отдельную таблицу и писать туда не только пары непосредственных
parent\child, но и вообще всех child'ов данного parent'а. Другой подход описания
дерева с помощью границ множеств есть у Celko (и у DK на сайте). Также можно
хранить
путь к корню дерева в строке в виде ID всех родителей разделённых спец.
сепаратором.
Полно вариантов, не нужно останавливаться на классическом id, parent_id...
У меня не получается выразить с помощью СТЕ задачи требующие прохода
снизу вверх по дереву.
Условие связки меняешь на обратное и начинаешь обход с нижнего уровня.
П. С.
Пробуя написать подсчёт детей породил такого вот монстрика.
with recursive
TREE (LEV, ID, PARENT_ID) as (
select
1 as LEV, s0.ID, s0.PARENT_ID
from SYMPTOMS s0 where s0.PARENT_ID is null
union all
select
t.LEV + 1, s1.ID, s1.PARENT_ID
from SYMPTOMS s1 inner join TREE t on s1.PARENT_ID = t.ID
),
TREE_C (IDD, LEV, GRANDAD_ID, PARENT_ID) as (
select
s.ID, t.LEV, t.ID as GRANDAD_ID, t.PARENT_ID
from SYMPTOMS s inner join TREE t on s.PARENT_ID = t.ID
union all
select
sc.ID, tc.LEV, tc.GRANDAD_ID as GRANDAD_ID, tc.PARENT_ID
from SYMPTOMS sc inner join TREE_C tc on sc.PARENT_ID = tc.IDD
)
select
t.LEV, t.GRANDAD_ID, t.PARENT_ID, count