Хорошие обзоры
Вообще говоря, вы выбираете между быстрым временем чтения (например, вложенный набор) или быстрым временем записи (список смежности). Обычно вы получаете комбинацию нижеприведенных вариантов, которая наилучшим образом соответствует вашим потребностям. Ниже приводится более подробное чтение:
- Еще одно сравнение вложенных интервалов и списка смежности: лучшее сравнение списка смежности, материализованного пути, вложенного набора и вложенного интервала, которые я нашел.
- Модели для иерархических данных: слайды с хорошими объяснениями компромиссов и примером использования
- Представление иерархий в MySQL: очень хороший обзор вложенного набора, в частности
- Иерархические данные в РСУБД: наиболее полный и хорошо организованный набор ссылок, который я видел, но не очень удобный для объяснения
Параметры
Известные мне и общие особенности:
- Столбцы: ID, ParentID
- Легко внедрить.
- Дешевый узел перемещает, вставляет и удаляет.
- Дорогой поиск уровня, происхождения и потомков, путь
- Избегайте N + 1 с помощью общих табличных выражений в базах данных, которые их поддерживают
- Вложенный набор (также известный как измененный обход дерева предзаказов)
- Столбцы: левый, правый
- Дешевая родословная, потомки
- Очень дорогое
O(n/2)
перемещает, вставляет, удаляет из-за изменчивого кодирования
- Таблица моста (также известная как Таблица закрытия / триггеры)
- Использует отдельную таблицу соединения с: предком, потомком, глубиной (необязательно)
- Дешевая родословная и потомки
- Записывает стоимость
O(log n)
(размер поддерева) для вставки, обновления, удаления - Нормализованная кодировка: подходит для статистики СУБД и планировщика запросов в соединениях
- Требуется несколько строк на узел
- Столбец происхождения (он же Материализованный путь, перечисление путей)
- Столбец: происхождение (например, / parent / child / grandchild / и т. Д.)
- Дешевые потомки через префиксный запрос (например,
LEFT(lineage, #) = '/enumerated/path'
) - Записывает стоимость
O(log n)
(размер поддерева) для вставки, обновления, удаления - Нереляционный: полагается на тип данных Array или сериализованный строковый формат
- Как вложенный набор, но с вещественным / плавающим / десятичным числом, так что кодировка не является изменчивой (недорогое перемещение / вставка / удаление)
- Имеет проблемы с вещественным / плавающим / десятичным представлением / точностью
- Вариант матричного кодирования добавляет кодировку предка (материализованный путь) для "бесплатного", но с дополнительными сложностями линейной алгебры.
- Измененный список смежности, который добавляет столбцы уровня и ранга (например, порядок) к каждой записи.
- Недорогое выполнение итерации / разбивки на страницы по
- Дорогой перенос и удаление
- Хорошее применение: обсуждение в форумах / блогах
- Несколько столбцов происхождения
- Столбцы: по одному для каждого уровня происхождения, относится ко всем родителям до корня, уровни вниз от уровня элемента устанавливаются на NULL
- Дешевые предки, потомки, уровень
- Дешевая вставка, удаление, перемещение листьев
- Дорогостоящая вставка, удаление, перемещение внутренних узлов
- Жесткое ограничение глубины иерархии
Примечания к базе данных
MySQL
Oracle
- Используйте CONNECT BY для просмотра списков смежности
PostgreSQL
- Тип данных ltree для материализованного пути
SQL Server
- Общая информация
- 2008 предлагает тип данных HierarchyId, чтобы помочь с подходом Lineage Column и расширить глубину, которая может быть представлена.
Согласно slideshare.net/billkarwin/sql-antipatterns-strike-back страница 77,
Closure Tables
превосходитAdjacency List
,Path Enumeration
иNested Sets
с точки зрения простоты использования Я тоже угадываю производительность).Здесь мне не хватает очень простой версии: простого BLOB. Если в вашей иерархии есть только несколько элементов, сериализованное дерево идентификаторов может быть лучшим вариантом.
@Lothar: вопрос - это вики сообщества, так что не стесняйтесь. Я думаю в этом отношении, что я бы сделал это только с теми базами данных, которые поддерживают какую-то структуру блобов, такую как XML, со стабильным языком запросов, таким как XPATH. В противном случае я не вижу хорошего способа запроса, кроме извлечения, десериализации и изменения кода, а не SQL. И если у вас действительно есть проблема, когда вам нужно много произвольных элементов, вам может быть лучше использовать базу данных Node, такую как Neo4J, которую я использовал и любил, хотя никогда не использовался в производстве.
Для MS SQL Server: Комбинация подходов Id-ParentId и HierarchyId к иерархическим данным
Ссылка MSDN на «Общее резюме» больше не отображает статью. Это было в выпуске MSDN Magazine за сентябрь 2008 г., который вы можете загрузить в виде файла CHM или просмотреть в веб-архиве по адресу: web.archive.org/web/20080913041559/http://msdn.microsoft.com : 80 /…