Ответ
Иерархическая таблица — это способ хранения данных с древовидной структурой (отношения «родитель-потомок») в реляционной БД. Каждая запись (узел) может ссылаться на свою родительскую запись.
Основные модели хранения иерархий в SQL:
-
Adjacency List (Список смежности)
- Самая простая модель. Каждая строка содержит ссылку на своего родителя (
parent_id). - Пример таблицы
categories:CREATE TABLE categories ( id INT PRIMARY KEY, name VARCHAR(100), parent_id INT NULL, FOREIGN KEY (parent_id) REFERENCES categories(id) ); - Запрос прямых потомков:
SELECT * FROM categories WHERE parent_id = 5; - Недостаток: Сложные рекурсивные запросы (получение всего поддерева) требуют рекурсивных CTE (Common Table Expressions) или множественных JOIN.
- Самая простая модель. Каждая строка содержит ссылку на своего родителя (
-
Nested Sets (Вложенные множества)
- Каждый узел имеет границы
leftиright. Все потомки находятся внутри этих границ. - Преимущество: Быстрое получение всего поддерева одним запросом.
- Недостаток: Сложность вставки/обновления узлов (требуется пересчет границ).
- Каждый узел имеет границы
-
Materialized Path (Материализованный путь)
- В строке хранится полный путь от корня до узла (например,
1.5.12.20). - Пример:
path VARCHAR(255). - Преимущество: Простота поиска по пути и поддереву с помощью
LIKE.
- В строке хранится полный путь от корня до узла (например,
Когда использовать? Для хранения структур каталогов, комментариев с ветвлением, организационных диаграмм.
Ответ 18+ 🔞
А, ну это же классика, блядь! Иерархическая таблица — это когда у тебя в базе данных сидит целое генеалогическое древо, как у этих ёбаных королевских семей, только без инцеста (в идеале). Каждая запись — это как член семьи: у кого-то есть родитель, а кто-то — сам корень, папаша, с которого всё начинается.
Смотри, как это обычно хранят, этих деревянных человечков в таблицах. Способов — овердохуища, но три главных, как три богатыря, только не такие могучие, у каждого свои косяки.
1. Список смежности (Adjacency List)
Это как самый простой способ, по-деревенски. Каждый узел знает только своего прямого батьку. В таблице просто лежит parent_id. Всё, пиздец, простота.
CREATE TABLE categories (
id INT PRIMARY KEY,
name VARCHAR(100),
parent_id INT NULL,
FOREIGN KEY (parent_id) REFERENCES categories(id)
);
Хочешь найти непосредственных отпрысков какого-нибудь узла? Легко, хуле:
SELECT * FROM categories WHERE parent_id = 5;
А вот чтобы достать ВСЁ его племя, всех внуков и правнуков до седьмого колена — тут уже начинается пиздец. Придётся либо рекурсивные CTE городить, которые не каждый SQL-движок с первого раза переварит, либо JOIN'ов накручивать столько, что сервер взвоет. Недостаток, блядь, налицо.
2. Вложенные множества (Nested Sets)
А это уже для хитрожопых математиков. Каждому узлу дают два числа: left и right. И все его детишки сидят аккурат между этими цифрами. Получить целое поддерево — раз плюнуть, один запрос.
Но, ёпта, попробуй вставить нового сыночка куда-нибудь в середину! Придётся пересчитывать границы у половины таблицы, всё разъёбывать и собирать заново. Операция вставки превращается в такой трэш, что проще новую таблицу создать. Не для жизни, а для спокойного, закэшированного справочника.
3. Материализованный путь (Materialized Path)
Тут вообще просто, как три копейки. В каждой строке пишешь весь путь от корня до этой записи, через точки: 1.5.12.20. Типа, "я сын того, кто сын того, кто сын вон того корня".
И чтобы найти всех потомков, тупо ищешь WHERE path LIKE '1.5.12.%'. Гениально и тупо одновременно. Но строки длинные получаются, индексы могут плакать.
Короче, когда это юзать? Да когда угодно, блядь! Каталоги товаров, где "Электроника" -> "Смартфоны" -> "Чехлы для смартфонов, которые разъебываются через неделю". Древовидные комментарии, где один мудак ответил другому мудаку, и понеслась. Оргструктура компании, где ты в самом низу, а над тобой — пидарас шерстяной, который только и делает, что слазит тебе в жопу с отчётами. В общем, везде, где есть эта ёбаная иерархия, сука. Выбирай модель по обстоятельствам, а то охуеешь потом переделывать.