|
|
|
| Есть у меня дерево со схемой nested sets + adjacency list. Нужно получить ветку дерева, но с сортировкой в узлах по произвольному полю.
Было:
root
- 1
-- 1.1
-- 1.2
-- 1.3
---- 1.3.1
---- 1.3.2
---- 1.3.3
-- 1.4
-2
-- 2.1
-- 2.2
| Это выполнился типичный запрос "... ORDER BY left_key".
Хочу получить:
root
-2
-- 2.1
-- 2.2
- 1
-- 1.3
---- 1.3.2
---- 1.3.1
---- 1.3.3
-- 1.1
-- 1.4
-- 1.2
| Тут узлы сортируются по полу "sort".
Каждый пользователь сам настраивает себе сортировку. Кто по имени элемента, кто по полю "sort", кто ещё по какому-нибудь полю, причём как с прямым, так и обратным направлением сортировки. Так что взять и предварительно отсортировать узлы прямо в базе нельзя. По сути, не имеет значения в каком порядке они хранятся в базе. Порядок определяется при выборке.
На самом деле я решил эту задачу на уровне РНР. Но хотелось бы всю сортировку скинуть на mysql, так как на больших деревьях скрипт отрабатывает неприлично долго. И возможно ли это вообще? | |
|
|
|
|
|
|
|
для: Саня
(13.01.2010 в 19:26)
| | Самый вкусный бонус от Nested Sets (вывод за 1 запрос предварительно упорядоченного набора узлов) потерян.
Имеет смысл вернуться к Adj Lists, ну и дальше долбить не отвлекаясь.
Дерево-то большое? | |
|
|
|
|
|
|
|
для: Trianon
(13.01.2010 в 19:39)
| | Около двух миллионов записей, максимальная высота — 7. Обычно юзеры экспортируют не более 1000 элементов за раз, но иногда требуется выбрать 100000 и более.
Список смежности там только для контроля целостности дерева. Даже отдельно написана утилита на си, по расписанию проверяющая и автоматически восстанавливающая дерево.
SELECT
catalog.id,
catalog.name
FROM
tree as t1,
tree as t2,
catalog
WHERE
t1.id=".$id." and
t2.left between t1.left+1 and t1.right-1 and
t2.level = t1.level+1 and
t2.id=catalog.id
ORDER BY
catalog.name
| Что скажете? А то я сейчас не могу проверить на реальной базе, а мозг уже отключается, чтобы понять это по тексту запроса. Либо я это узнаю сегодня от вас, либо завтра сам :) | |
|
|
|
|
|
|
|
для: Саня
(13.01.2010 в 19:55)
| | Для одного подуровня - верно.
Так а поля parent_id в таблице нет? | |
|
|
|
|
|
|
|
для: Trianon
(13.01.2010 в 20:11)
| | Есть конечно. Это же основа AL. | |
|
|
|
|
|
|
|
для: Саня
(13.01.2010 в 20:52)
| | так проще ж по id - parent_id связать t1 и t2 | |
|
|
|
|
|
|
|
для: Trianon
(13.01.2010 в 23:38)
| | Не понял. Предлагаете рекурсию оформить? | |
|
|
|
|
|
|
|
для: Саня
(14.01.2010 в 13:47)
| | Да нет же.
Предлагаю
t2.left between t1.left+1 and t1.right-1 and
t2.level = t1.level+1 and
| поменять на
| |
|
|
|
|
|
|
|
для: Trianon
(14.01.2010 в 16:08)
| | В итоге поменяли шило на мыло. Ну да ладно. Всё равно мое решение временное и будет заменено программой на си, когда сишник освободится с другого проекта. | |
|
|
|