Реентерабельные соединения
Реентерабельные соединения
Условия проектирования иногда требуют формирования объединенного набора из двух или более потоков, которые поступают из одной и той же таблицы. Часто таблица проектируется с иерархической, или древовидной, структурой, где каждая строка в таблице логически является потомком родителя в той же таблице. Первичный ключ таблицы указывает на узел дерева уровня потомка, в то время как колонка внешнего ключа хранит родительский ключ, ссылающийся на значение первичного ключа в другой строке.
Запрос на "выравнивание" отношения родитель-потомок требует соединения, которое извлекает один поток для родителей, а другой - для потомков из той же таблицы. Обычный термин для этого - ссылающееся на себя соединение. Термин реентерабельное соединение морфологически является более подходящим, т. к. существуют другие типы реентерабельных запросов, которые не используют соединений. Позже в этой главе в разд. "Подзапросы" обсуждаются другие типы реентерабельных запросов.
Курсоры для реентерабельных соединений
Для выполнения реентерабельного соединения сервер поддерживает один внутренний курсор для каждого потока в пределах образа одной таблицы. Концептуально он трактует контексты двух курсоров, как если бы они были отдельными таблицами. В этой ситуации синтаксис ссылок на таблицу обязательно использует алиасы для различения курсоров двух потоков.
В следующем примере каждое подразделение организации хранится с родительским идентификатором, который указывает на первичный ключ его руководящего подразделения. Приведенный далее запрос трактует подразделения и родительские подразделения, как если бы они были двумя таблицами:
SELECT
D1.XD,
D1.PARENTID,
D1.DESCRIPTION AS DEPARTMENT,
D2.DESCRIPTION AS PARENT_DEPT
FROM DEPARTMENT D1
LEFT JOIN DEPARTMENT D2
/* левое соединение обращается к корню дерева, ID 100 */
ON Dl.PARENTID = D2.ID;
На рис. 22.6 проиллюстрировано, как выбираются записи потомков в реентерабельном обращении к таблице DEPARTMENT.
Рис. 22.6. Внутренние курсоры для простого реентерабельного соединения Простой двухуровневый результат показан на рис. 22.7.
Результат этого запроса очень простой - одноуровневая денормализация. Операции получения древовидного результата для таблиц такого вида часто являются рекурсивными, они используют хранимые процедуры для реализации и управления рекурсией[79].
Рис. 22.7. Результат простого реентерабельного соединения