Общие > Базы данных
Nested Set Поменять ветки местами на одном уровне
Phoinix:
Есть дерево Nested Set
Что бы переместить один узел на одну позицию выше (ниже) на том же уровне приходится делать несколько лишних манипуляций, а точнее:
1. Выбираем узел который перемещаем:
SELECT left_key, right_key, level FROM table WHERE id = $id
получаем: $left_key, $right_key и $level
2. Выбираем узел который выше по порядку (ниже - запрос аналогичен):
SELECT left_key, right_key FROM table WHERE right_key = $left_key - 1 AND level = $level
получаем: $left_key_up и $right_key_up
Получаем смещения ключей каждого узла:
$skew1 = $right_key - $left_key + 1
$skew2 = $right_key_up - $left_key_up + 1
Теперь, казалось бы, что можно просто в первой ветке уменьшить значения ключей на смещение ключей второй ветки, а во второй увеличить ключи на смещение ключей первой, но данная операция производится в два запроса и во время второго запроса меняются записи которые были уже изменены в первом. Поэтому приходится предварительно выбирать все идентификаторы подчиненных узлов перемещаемого узла, и делать изменения не относительно ключей а относительно идентификаторов:
3. Выбираем идентификаторы:
SELECT id FROM table WHERE left_key >= $left_key AND right_key = $left_key_up AND right_key
Phoinix:
В голову приходит только объединение 1 и 3 запроса в один:
SELECT t1.id, t2.left_key, t2.right_key, t2.level
FROM table AS t1, table AS t2
WHERE t2.id = 20 AND t1.left_key >= t2.left_key AND t1.right_key
Макс:
перемещение узлов происходит не так часто чтобы его оптимизировать.
Не пробовал объединить выборку всех идентификаторов, которые нужно переместить и само перемещение? То есть вместо запросов
SELECT id FROM table WHERE left_key >= $left_key AND right_key = $left_key AND right_key
Макс:
твой код основан на
http://phpclub.ru/talk/showthread.php?s=&threadid=30774&perpage=20&pagenumber=2
?
Если да, то он писался давно и тогда я еще не совсем разобрался с Nested Sets
Phoinix:
Макс
--- Цитировать ---твой код основан на
--- Конец цитаты ---
Нет... честно говоря, это не видел...
--- Цитировать ---Не пробовал объединить выборку всех идентификаторов, которые нужно переместить и само перемещение? То есть вместо запросов
--- Конец цитаты ---
В том-то и дело, что пробовал, но при перемещении первой ветки (не зависимо от какой) ключи очень часто попадают в диапазон выборки второго запроса, Например:
--- Код: ---
Ветка 1 [1][1][6]
Ветка 1-1 [2][2][3]
Ветка 1-2 [2][4][5]
Ветка 2 [1][7][12]
Ветка 2-1 [2][8][9]
Ветка 2-2 [2][10][11]
--- Конец кода ---
Нужно "Ветку 2" поднять выше "Ветки 1"
При обновлении ключей "Ветки 2" получается:
--- Код: ---
Ветка 1 [1][1][6]
Ветка 1-1 [2][2][3]
Ветка 1-2 [2][4][5]
Ветка 2 [1][1][6]
Ветка 2-1 [2][2][3]
Ветка 2-2 [2][4][5]
--- Конец кода ---
И если мы захотим сделать обновление ключей "Ветки 1", то мы уже не можем брать в запросе диапазон ключей "Ветки 1" т.к. В него попадут узлы "Ветки 2"
P.S. Появилась новая мысль... попробую проверить ... :)
Навигация
Перейти к полной версии