Что такое иерархическая таблица в базах данных?

Ответ

Иерархическая таблица — это способ хранения данных с древовидной структурой (отношения «родитель-потомок») в реляционной БД. Каждая запись (узел) может ссылаться на свою родительскую запись.

Основные модели хранения иерархий в SQL:

  1. 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.
  2. Nested Sets (Вложенные множества)

    • Каждый узел имеет границы left и right. Все потомки находятся внутри этих границ.
    • Преимущество: Быстрое получение всего поддерева одним запросом.
    • Недостаток: Сложность вставки/обновления узлов (требуется пересчет границ).
  3. 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.%'. Гениально и тупо одновременно. Но строки длинные получаются, индексы могут плакать.

Короче, когда это юзать? Да когда угодно, блядь! Каталоги товаров, где "Электроника" -> "Смартфоны" -> "Чехлы для смартфонов, которые разъебываются через неделю". Древовидные комментарии, где один мудак ответил другому мудаку, и понеслась. Оргструктура компании, где ты в самом низу, а над тобой — пидарас шерстяной, который только и делает, что слазит тебе в жопу с отчётами. В общем, везде, где есть эта ёбаная иерархия, сука. Выбирай модель по обстоятельствам, а то охуеешь потом переделывать.