Некоторое время я боролся с тем, как лучше обрабатывать иерархии в SQL. Разочарованный ограничениями списков смежности и сложностью наборов MPTT/вложенных наборов, я начал думать о простом хранении ключевых путей вместо простой строки node_key/node_key/...
. Я решил собрать плюсы и минусы трех методов:
Количество вызовов, необходимых для создания/удаления/перемещения a node:
- Adjacency = 1
- MPTT = 3
- Path = 1 (Замените старый node путь с новым node контуром для всех узлов, которые содержат этот путь)
Количество вызовов, необходимых для получения дерева:
- Adjacency = [количество подуровней]
- MPTT = 1
- Путь = 1
Количество вызовов, необходимых для получения пути к node/ancestry:
- Adjacency = [количество суперуровней]
- MPTT = 1
- Путь = 0
Количество вызовов, необходимых для получения количества подносов:
- Adjacency = [количество подуровней]
- MPTT = 0 (может быть рассчитан из значений справа/слева)
- Путь = 1
Количество вызовов, необходимых для получения глубины node:
- Adjacency = [количество суперуровней]
- MPTT = 1
- Путь = 0
Требуемые поля БД:
- Adjacency = 1 (родительский)
- MPTT = 3 (родительский, правый, левый)
- Путь = 1 (путь)
Заключение
Метод сохраненного пути использует одни и те же или менее вызовы, чем другие методы в каждом случае, кроме одного. По этому анализу сохранение путей является явным победителем. Не говоря уже о том, что это намного проще реализовать, удобочитаемый и т.д.
Итак, вопрос в том, должны ли хранимые пути считаться более сильным, чем MPTT? Почему сохраненные пути не являются более часто используемой техникой и почему вы не используете их в MPTT в данном случае?
Кроме того, если вы считаете, что этот анализ неполный, пожалуйста, дайте мне знать.
UPDATE:
Вот, по крайней мере, 2 вещи, которые MPTT может сделать из коробки, что не будет сохраненного пути:
- Позволяет вычислять подсчет субномов для каждого node без каких-либо дополнительных запросов (упомянутых выше).
- Накладывает порядок на узлы на заданном уровне. Другие решения неупорядочены.