Хорошие обзоры
Вообще говоря, вы принимаете решение между быстрыми временами чтения (например, вложенным набором) или быстрым временем записи (список смежности). Как правило, вы получаете комбинацию из следующих вариантов, которые наилучшим образом соответствуют вашим потребностям. Ниже приводится некоторое углубленное чтение:
- Еще одно сравнение вложенных интервалов с сопоставлением списка привязанностей: лучшее сравнение списка смежности, материализованного пути, вложенного набора и вложенного интервала, который я нашел.
- Модели для иерархических данных: слайды с хорошими объяснениями компромиссов и использования примера
- Представление иерархии в MySQL: очень хороший обзор вложенного набора, в частности
- Иерархические данные в РСУБД: наиболее полный и хорошо организованный набор ссылок, которые я видел, но не так много объяснений
Опции
Я знаю и общие особенности:
- Список аджанс:
- Столбцы: ID, ParentID
- Легко реализуется.
- Дешевые узлы перемещаются, вставляются и удаляются.
- Дорого, чтобы найти уровень, родословную и потомки, путь
- Избегайте N + 1 через общие табличные выражения в базах данных, которые их поддерживают
- Вложенный набор (также измененный обход дерева предзаказов)
- Столбцы: влево, вправо
- Дешевая родословная, потомки
- Очень дорогое
O(n/2)
перемещает, вставляет, удаляет из-за изменчивого кодирования
- Таблица моста (aka Closure Table/w триггеры)
- Использует отдельную таблицу соединений с: предком, потомком, глубиной (необязательно)
- Дешевая родословная и потомки
- Записывает затраты
O(log n)
(размер поддерева) для вставки, обновления, удаления - Нормализованное кодирование: полезно для статистики РСУБД и планировщика запросов в соединениях
- Требует несколько строк на узел
- Столбец Lineage (также называемый Materialized Path, Path Enumeration)
- Колонка: lineage (например,/parent/child/grandchild/etc...)
- Дешевые потомки через префиксный запрос (например,
LEFT(lineage, #) = '/enumerated/path'
) - Записывает затраты
O(log n)
(размер поддерева) для вставки, обновления, удаления - Non-relational: полагается на тип данных Array или последовательный формат строки
- Вложенные интервалы
- Как вложенный набор, но с real/float/decimal, чтобы кодировка не была изменчивой (недорогой move/insert/delete)
- Имеет реальные/плавающие/десятичные представления/точность
- Матричный вариант кодирования добавляет кодирование предка (материализованный путь) для "свободного", но с добавленной хитростью линейной алгебры.
- Плоский стол
- Измененный список смежности, который добавляет столбец уровня и ранга (например, упорядочение) к каждой записи.
- Дешево для итерации /paginate
- Дорогой ход и удаление
- Хорошее использование: обсуждение темы - форумы/комментарии в блоге
- Несколько столбцов линии
- Столбцы: по одному для каждого уровня линии, относятся ко всем родителям до корня, уровни вниз от уровня предмета устанавливаются в NULL
- Дешевые предки, потомки, уровень
- Дешевая вставка, удаление, перемещение листьев
- Дорогое вставка, удаление, перемещение внутренних узлов
- Жесткий предел того, насколько глубока иерархия
Специфические примечания к базе данных
MySQL
оракул
- Используйте CONNECT BY для перемещения списков Adjacency
PostgreSQL
- Тип данных для материализованного пути
SQL Server
- Общее резюме
- 2008 предлагает тип данных HierarchyId, который помогает с помощью подхода Lineage Column и расширяет глубину, которая может быть представлена.