Перемещение узла в Nested Sets

BoFFiN

Новичок
Перемещение узла в Nested Sets

Никак не могу разобраться, как узел перемещать...
Например, есть дерево:
•Home
••Moskow
•••Photo
••London
•••Photo
•••Story
Хочу получить такое дерево:
•Home
••Moskow
•••Photo
•••Story
••London
•••Photo
Делаю:

1. Ключи и уровень перемещаемого узла:
SELECT level, left_key, right FROM my_tree WHERE = $id
в нашем случае $id = 6, получаем соотвественно level = 3, left_key = 6, right_key = 7

2. Уровень нового родительского узла:
SELECT level FROM my_tree WHERE id = $id_up
в нашем случае $id_up = 2, получаем level($level_up) = 2

3. Правый ключ узла за который мы вставляем узел (ветку):
Данная переменная берется в зависимости от действия:
a)При простом перемещении в другой узел; (т.е. мой случай)
SELECT (right_key – 1) AS right_key FROM my_tree WHERE id = 2 #[id нового родительского узла]

4. Определяем смещения:
$level_up - $level + 1 = $skew_level - смещение уровня изменяемого узла;
$right_key - $left_key + 1 = $skew_tree - смещение ключей дерева;
соотвественно:
2-3+1 = 0
6-7+1=0
дальше не буду продолжать, так как уже не прально, имхо, как может быть смещения 0, что не так делаю?!
Статья Дерево каталогов NESTED SETS (вложенные множества) и управление им
З.Ы. Спасибо
 

BoFFiN

Новичок
чуть не забыл, класс phpDbTree не предлагать...

-~{}~ 03.03.05 19:17:

vladax
http://phpclub.ru/talk/showthread.p...3449#post213449
...
// находим узел, с которым нужно поменять местами указанный
Всмысле поменять?!
 

BoFFiN

Новичок
Макс
млин... так не хотелось в классе разбираться.. может легче сказать, какие запросы нужно сделать, или где у меня ошибка?
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
Автор оригинала: BoFFiN
Никак не могу разобраться, как узел перемещать...
перемещение узла вообще говоря можно представить как две операции:
1) удаление узла
2) вставка узла

для обоих этих операций вполне понятно как должны изменяться "левое" и "правое" значения. ну и принять во внимание тот факт, что у некоторых узлов эти изменения взаимно уничтожатся.

ну и плюс сдвинуть "левое" и "правое" значения на самой перемещаемой ветке.

сам недавно мучался с этой задачей, решением поделиться могу, но это процедура на pl/pgsql
 

BoFFiN

Новичок
Макс
Я, как понимаю, ты соавтор статьи, которую я указал выше(Maxim Matyukhin)... В этой статье, описано Создание узла, Удаление узла, Перемещение узла... Создание и удалением всё понятно. Перемещение узла вообще правильно в статье описано?!

и еще... в статье описана проверка целостности ключей:
...
4. SELECT id, MOD((right_key - left_key) / 2) AS ostatok FROM my_tree WHERE ostatok = 0

Если все правильно то результата работы запроса не будет, иначе, получаем список идентификаторов неправильных строк;

5. SELECT id, MOD((left_key – level + 2) / 2) AS ostatok FROM my_tree WHERE ostatok = 1

Если все правильно то результата работы запроса не будет, иначе, получаем список идентификаторов неправильных строк;
...
эти запросы дают ошибку...

Sad Spirit
спасибо...

-~{}~ 04.03.05 09:21:

Говоря конкретно:
PHP:
UPDATE my_table
SET left_key = IF(right_key <= $right_key, left_key + $skew_edit, IF(left_key > $right_key, left_key - $skew_tree, left_key)),
level = IF(right_key <= $right_key, level + $skew_level, level),
right_key = IF(right_key <= $right_key, right_key + $skew_edit, IF(right_key <= $right_key_near, right_key - $skew_tree, right_key))
WHERE right_key > $left_key AND left_key <= $right_key_near
этот запрос верный для перемещения???

-~{}~ 04.03.05 09:39:

сейчас выполнил этот запрос для перемещения одного узла, вроде всё прально.. По-крайнее мере проверка прошла:
1. Левый ключ ВСЕГДА меньше правого;
2. Наименьший левый ключ ВСЕГДА равен 1;
3. Наибольший правый ключ ВСЕГДА равен двойному числу узлов;
4. Разница между правым и левым ключом ВСЕГДА нечетное число;
5. Если уровень узла нечетное число то тогда левый ключ ВСЕГДА нечетное число, то же самое и для четных чисел;
6. Ключи ВСЕГДА уникальны, вне зависимости от того правый он или левый;

-~{}~ 04.03.05 09:46:

мдя.. рано радовался..
2. Выбор подчиненных узлов
SELECT id, name, level FROM my_tree WHERE left_key >= $left_key AND right_key <= $right_key ORDER BY left_key
работает на правильно.. :(
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
Автор оригинала: BoFFiN
этот запрос верный для перемещения???
Нет, потому что он не обрабатывает детей перемещаемой рубрики.
 

Макс

Старожил PHPClub
Я, как понимаю, ты соавтор статьи, которую я указал выше(Maxim Matyukhin)... В этой статье, описано Создание узла, Удаление узла, Перемещение узла... Создание и удалением всё понятно. Перемещение узла вообще правильно в статье описано?!
Перемещение автор писал сам и я его не проверял.
Я перемещение делал совсем по другому (см класс DBTree).
Объяснить перемещение я не могу - просто не помню как делал (пару дней с бумагой сидел, вычислял формулы)

-~{}~ 04.03.05 15:37:

...
4. SELECT id, MOD((right_key - left_key) / 2) AS ostatok FROM my_tree WHERE ostatok = 0

Если все правильно то результата работы запроса не будет, иначе, получаем список идентификаторов неправильных строк;

5. SELECT id, MOD((left_key – level + 2) / 2) AS ostatok FROM my_tree WHERE ostatok = 1

Если все правильно то результата работы запроса не будет, иначе, получаем список идентификаторов неправильных строк;
...

эти запросы дают ошибку...
какую именно ошибку ?
Вроде все верно
 

BoFFiN

Новичок
SQL ошибка при выполнении(1064). Ответ сервера:
You have an error in your syntax. Check the manual that corresponds your Mysql server version fot the
right to use syntax near ') AS ostatok FROM section WHERE ostatok=0' at line 1

Mysql version: 4.0.21
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
Автор оригинала: BoFFiN
Так в моём случае, у родителя нет детей...
Тогда не парься с перемещением, а просто делай "удалить узел" и "добавить узел".
 

BoFFiN

Новичок
Sad Spirit

Ок... видимо придёться пока так сделать... пока не разберусь...
 

BoFFiN

Новичок
GeT
я знаю, первый пост прочти, как раз ссылка дана именно на эту статью
 
Сверху