Поиск в иерархии
От: naf_2000  
Дата: 08.10.09 06:22
Оценка:
есть таблицы
create table T(
ID integer not null primary key,
Name varchar(100),
Parent integer --ссылка на запись этой же таблицы, для верхнего уровня NULL (без зацикливаний)
)
create table R(
ID integer not null primary key,
TID integer not null unique, --ссылка на элемент таблицы T
Val integer
)

требуется написать хранимую процедуру GetVal(aT integer), получающую на входе ключ таблицы T, на выходе значение Val, определеяемое по правилу:
если есть запись в
select Val from R where TID=:aT

то берем ее, иначе вычисляем для родителя GetVal(aT.Parent) и т.д.. Если нет в иерархии, то NULL.
Требуется оптимальное по скорости решение
Re: Поиск в иерархии
От: Мурлакотам Россия  
Дата: 08.10.09 06:45
Оценка:
Здравствуйте, naf_2000, Вы писали:

_>Поиск в иерархии

_>Требуется оптимальное по скорости решение

AFAIK, длительность поиска по иерархии — факт, на который повлиять средствами реляционных СУБД невозможно. Сам в таких случая применял два подхода:
1. Велосипедный. Вся иерархия считывается в собственную структуру данных и далее поиск производится уже в ней (либо рекурсивно, либо по развёрнутому плоскому представлению, построенному предварительно с применением рекурсии).
2. Использование иерархических СУБД. Иерархическая часть БД выносится на альтернативный движок (например, в LDAP), который и решает задачу поиска по иерархии.
Re: Поиск в иерархии
От: VVP Россия 67524421
Дата: 08.10.09 06:46
Оценка:
Здравствуйте, naf_2000, Вы писали:
_>
_>create table T(
_>create table R(
_>

_>требуется написать хранимую процедуру GetVal(aT integer), получающую на входе ключ таблицы T, на выходе значение Val, определеяемое по правилу:
_>если есть запись в
_>
_>select Val from R where TID=:aT_>

_>то берем ее, иначе вычисляем для родителя GetVal(aT.Parent) и т.д.. Если нет в иерархии, то NULL.
_>Требуется оптимальное по скорости решение

Оптимально будет делать цикл (на T-SQL) с запросами значения R.Val для основного значения T.ID, для иерархии его родителей, пока не будет обнаружено заданное значение R.Val или не кончится иерархия.

Сходили на собеседование в Связной?
Только там требовалось решение для 5-уровневой иерархии на языке 1С8 (запросы + модуль).
Например, такой цикл в 7 раз быстрее одного запроса с 5-ю объединениями (при индексации всех FK, конечно).
Никогда не бойся браться делать то, что делать не умеешь. Помни, ковчег был построен любителем. Профессионалы построили Титаник...
Re: Поиск в иерархии
От: Овощ http://www.google.com
Дата: 08.10.09 07:35
Оценка: 1 (1)
Здравствуйте, naf_2000.

Похоже на Oracle. Поэтому будем считать что это Oracle.

Можно все сделать одним запросом:
select T.*, R.*
from T
    left join R
        on T.ID = R.TID
where R.ID is not null
start with T.ID = :starting_t_id
connect by prior T.Parent = T.ID and prior R.ID is null


Для скорости возможно стоит подумать над тем, чтобы слить эти две таблицы в одну, избежав тем самым постоянного выполнения джойна этих двух таблиц при каждом выполнении запроса.
Re[2]: Поиск в иерархии
От: _d_m_  
Дата: 13.10.09 07:00
Оценка: +1
Здравствуйте, Мурлакотам, Вы писали:

М>Здравствуйте, naf_2000, Вы писали:


_>>Поиск в иерархии

_>>Требуется оптимальное по скорости решение

М>AFAIK, длительность поиска по иерархии — факт, на который повлиять средствами реляционных СУБД невозможно. Сам в таких случая применял два подхода:

М>1. Велосипедный. Вся иерархия считывается в собственную структуру данных и далее поиск производится уже в ней (либо рекурсивно, либо по развёрнутому плоскому представлению, построенному предварительно с применением рекурсии).

Так себе решение.

М>2. Использование иерархических СУБД. Иерархическая часть БД выносится на альтернативный движок (например, в LDAP), который и решает задачу поиска по иерархии.


Чушь.
Задача легко решается рекурсивным запросом и в обычных реляционных СУБД.
Re[2]: Поиск в иерархии
От: _d_m_  
Дата: 13.10.09 07:02
Оценка:
Здравствуйте, VVP, Вы писали:

VVP>Оптимально будет делать цикл (на T-SQL) с запросами значения R.Val для основного значения T.ID, для иерархии его родителей, пока не будет обнаружено заданное значение R.Val или не кончится иерархия.


Еще один "велосипедист"? Оптимально будет сделать рекурсивный запрос через Common Table Expression.
Re: Поиск в иерархии
От: _d_m_  
Дата: 13.10.09 07:04
Оценка: +1
Здравствуйте, naf_2000, Вы писали:

_>то берем ее, иначе вычисляем для родителя GetVal(aT.Parent) и т.д.. Если нет в иерархии, то NULL.

_>Требуется оптимальное по скорости решение

Как часто мне приходится задавать этот вопрос...
СУБД и ее версия?
Re[2]: Поиск в иерархии
От: G0ga  
Дата: 14.10.09 20:41
Оценка: 6 (1)
Здравствуйте, _d_m_, Вы писали:

___>Здравствуйте, naf_2000, Вы писали:


_>>то берем ее, иначе вычисляем для родителя GetVal(aT.Parent) и т.д.. Если нет в иерархии, то NULL.

_>>Требуется оптимальное по скорости решение

___>Как часто мне приходится задавать этот вопрос...

___>СУБД и ее версия?

Могу порекомендовать http://rsdn.ru/article/alg/dbtree.xml
Автор(ы): Сергей Виноградов
Дата: 16.11.2001
. Ингода помогает
Re[3]: Поиск в иерархии
От: Огнеплюх  
Дата: 14.10.09 21:39
Оценка:
Здравствуйте, _d_m_, Вы писали:

___>Здравствуйте, VVP, Вы писали:


VVP>>Оптимально будет делать цикл (на T-SQL) с запросами значения R.Val для основного значения T.ID, для иерархии его родителей, пока не будет обнаружено заданное значение R.Val или не кончится иерархия.


___>Еще один "велосипедист"? Оптимально будет сделать рекурсивный запрос через Common Table Expression.


Не велосипедист, а композитор ! )
http://www.rsdn.ru/forum/humour/3554785.1.aspx
Автор: Огнеплюх
Дата: 01.10.09
Re[2]: Поиск в иерархии
От: wildwind Россия  
Дата: 15.10.09 16:22
Оценка:
Здравствуйте, Овощ, Вы писали:

О>Похоже на Oracle.


Ты невнимателен.
Re[2]: Поиск в иерархии
От: avpavlov  
Дата: 18.10.09 16:03
Оценка:
VVP>Только там требовалось решение для 5-уровневой иерархии на языке 1С8 (запросы + модуль).
VVP>Например, такой цикл в 7 раз быстрее одного запроса с 5-ю объединениями (при индексации всех FK, конечно).

Чего-то имею я сомнения. Можешь примерно привести характеристики этой иерархии (сколько всего элементов, сколько корневых, второго уровня и т.д.), не поленюсь проверить у себя.
Re[3]: Поиск в иерархии
От: _d_m_  
Дата: 19.10.09 23:11
Оценка:
Здравствуйте, G0ga, Вы писали:

G>Здравствуйте, _d_m_, Вы писали:


___>>Здравствуйте, naf_2000, Вы писали:


_>>>то берем ее, иначе вычисляем для родителя GetVal(aT.Parent) и т.д.. Если нет в иерархии, то NULL.

_>>>Требуется оптимальное по скорости решение

___>>Как часто мне приходится задавать этот вопрос...

___>>СУБД и ее версия?

G>Могу порекомендовать http://rsdn.ru/article/alg/dbtree.xml
Автор(ы): Сергей Виноградов
Дата: 16.11.2001
. Ингода помогает



Могу предложить спустить эту статейку в... аналы истории. Судя по всему — в основе MS SQL, она была напечатана в 2001, устарела в 2005.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.