Открыть сервис

Тип данных HIERARCHYID

HIERARCHYID — это встроенный тип данных в системе управления базами данных Microsoft SQL Server, предназначенный для представления иерархических структур (деревьев) и выполнения операций с ними. Он позволяет хранить данные о положении узла в иерархии, обеспечивая эффективные запросы для поиска предков, потомков, соседних узлов и пути от корня. Тип был введён в версии SQL Server 2008 и реализован в виде системы CLR (Common Language Runtime), что обеспечивает компактное хранение и высокую производительность при работе с древовидными структурами, такими как организационные схемы, категории товаров, структуры сайтов или классификаторы.

История и предпосылки появления

До появления HIERARCHYID в реляционных базах данных иерархии моделировались несколькими способами, каждый из которых имел недостатки. Классическая модель «список смежности» (adjacency list), где каждый узел хранит ссылку на родительский узел (ParentID), проста в реализации, но требует рекурсивных запросов (например, Common Table Expressions) для получения всех потомков, что снижает производительность на больших глубинах. Модель «вложенные множества» (nested sets) использует левый и правый ключи для быстрого поиска поддеревьев, но сложна в обновлении при вставке или удалении узлов. Модель «материализованный путь» (materialized path) хранит полный путь от корня в виде строки (например, «1/3/7/»), но требует разбора строк и неэффективна для операций сравнения.

Разработчики Microsoft SQL Server создали HIERARCHYID как комбинацию преимуществ этих подходов, избегая их основных недостатков. Тип основан на двоичном представлении пути, что позволяет проводить сравнения, сортировку и поиск без рекурсии, а также обеспечивает компактное хранение (размер зависит от глубины, но обычно не превышает 892 байт). Внедрение CLR-интеграции позволило реализовать сложные методы для работы с иерархией непосредственно на сервере.

Структура и представление

HIERARCHYID представляет собой путь от корня дерева до конкретного узла. Каждый сегмент пути (уровень) кодируется как целое число, а весь путь преобразуется в бинарный формат. Внешне значение HIERARCHYID отображается в виде строки, например: /1/3/7/. Косая черта в начале обозначает корень, а последующие числа — номера дочерних узлов на каждом уровне. Корневой узел имеет представление /.

Ключевые характеристики:

Методы и функции

HIERARCHYID предоставляет набор встроенных методов для работы с иерархическими данными. Основные из них:

Статические методы

Экземплярные методы

Пример использования

Рассмотрим создание таблицы для хранения организационной структуры компании:

``sql CREATE TABLE Employees ( EmployeeID INT PRIMARY KEY, Name NVARCHAR(100), Position HIERARCHYID NOT NULL ); ``

Вставка корневого узла (генеральный директор): ``sql INSERT INTO Employees (EmployeeID, Name, Position) VALUES (1, 'Иван Петров', HIERARCHYID::GetRoot()); ``

Вставка дочерних узлов (руководители отделов). Для получения нового HIERARCHYID используется метод GetDescendant: ``sql DECLARE @root HIERARCHYID = (SELECT Position FROM Employees WHERE EmployeeID = 1); INSERT INTO Employees (EmployeeID, Name, Position) VALUES (2, 'Мария Сидорова', @root.GetDescendant(NULL, NULL)); -- Второй дочерний узел INSERT INTO Employees (EmployeeID, Name, Position) VALUES (3, 'Алексей Кузнецов', @root.GetDescendant( (SELECT Position FROM Employees WHERE EmployeeID = 2), NULL)); ``

Запрос всех подчинённых определённого руководителя: ``sql DECLARE @managerPos HIERARCHYID = (SELECT Position FROM Employees WHERE EmployeeID = 1); SELECT EmployeeID, Name, Position.ToString() AS Path FROM Employees WHERE Position.IsDescendantOf(@managerPos) = 1 ORDER BY Position; ``

Результат покажет всех сотрудников, начиная с корня, отсортированных в порядке обхода дерева.

Преимущества и недостатки

Преимущества

Недостатки

Сравнение с альтернативными подходами

ПодходХранениеПоиск потомковВставка/УдалениеПереносимость
Список смежностиParentIDРекурсивный CTEПростаяВысокая
Вложенные множестваLeft/RightБыстрыйСложная (сдвиг ключей)Средняя
Материализованный путьСтрокаLIKEСредняяВысокая
HIERARCHYIDБинарныйБыстрыйСредняяНизкая

HIERARCHYID занимает промежуточное положение по сложности операций, но превосходит другие подходы по скорости поиска и компактности хранения в рамках Microsoft SQL Server.

Применение в России

В российских компаниях и государственных учреждениях, использующих Microsoft SQL Server, HIERARCHYID применяется для моделирования организационных структур, классификаторов товаров (например, в системах электронной коммерции), иерархий документов и каталогов. Тип особенно популярен в проектах, где требуется часто выполнять запросы на получение всех дочерних элементов (например, в системах управления контентом или ERP-системах). Однако из-за политики импортозамещения и перехода на отечественные СУБД (например, Postgres Pro на базе PostgreSQL) использование HIERARCHYID в новых проектах может быть ограничено, так как в PostgreSQL аналогом является тип ltree, имеющий схожую функциональность, но иной синтаксис.

Критика и ограничения

Основная критика HIERARCHYID связана с его закрытостью и привязкой к экосистеме Microsoft. При попытке миграции на другую СУБД данные, хранящиеся в этом типе, требуют преобразования, что может быть нетривиальной задачей. Кроме того, метод GetDescendant не гарантирует глобальной уникальности вставки (если два пользователя одновременно вставят узел с одинаковым родителем и одинаковыми параметрами child1/child2, может возникнуть конфликт), что требует дополнительной синхронизации на уровне приложения. Некоторые разработчики отмечают, что для простых иерархий (глубиной до 3-5 уровней) традиционный список смежности с рекурсивными CTE может быть проще в реализации и поддержке.

Источники

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →