Не понимаю, как вычисляются ключи left и right, я никак понять не могу? Вот допустим, нужно такое дерево: Программирование -PHP -JS -Python Всего 4 узла. В первом правом ключе, будет произведение суммы всех узлов * на 2. 1 узел id = 1, level = 1, left = 1, right = 8 2 узел id =2 , level =2 , left = ? , right = ? Вот здесь я вообще не понимаю, как вычислять? Смотрю на картинку и не понимаю
Разобрался с добавлением подкатегории, поправьте меня, если я где-то ошибся. Вот такая структура, фото есть во вложении Код (Text): CREATE table language ( id serial, left_key INTEGER NOT NULL, right_key INTEGER NOT NULL, level INTEGER NOT NULL DEFAULT 0, name VARCHAR(50) NOT NULL ); INSERT INTO language (id, level, left_key, right_key, name) VALUES (1, 1, 1, 12, 'Языки'), (2, 2, 2, 5, 'PHP'), (3, 3, 3, 4, 'PHP7'), (4, 2, 6, 9, 'JS'), (5, 3, 7, 8, 'React'), (6, 2, 10, 11, 'HTML'); Вывод древовидного меню, без рекурсии и циклов Код (Text): SELECT repeat('.', language.level*2) || name, level FROM language ORDER BY left_key; Вот так должно быть Код (Text): postgres-# left_key; ?column? | level -------------+------- ..Языки | 1 ....PHP | 2 ......PHP7 | 3 ....JS | 2 ......React | 3 ....HTML | 2 (6 rows) Добавляю новую категорию Laravel в PHP. Код (Text): postgres=# select * FROM language; id | left_key | right_key | level | name ----+----------+-----------+-------+------- 1 | 1 | 12 | 1 | Языки 2 | 2 | 5 | 2 | PHP 3 | 3 | 4 | 3 | PHP7 4 | 6 | 9 | 2 | JS 5 | 7 | 8 | 3 | React 6 | 10 | 11 | 2 | HTML Для этого узнаю правый ключ у той категории, в которую добавляю и всем листочкам (у которых левый ключ больше) увеличиваю оба ключа на 2; Код (Text): UPDATE language SET left_key = left_key + 2, right_key = right_key + 2 WHERE left_key > 5; Проверяю, что получилось Код (Text): postgres=# select * FROM language; id | left_key | right_key | level | name ----+----------+-----------+-------+------- 1 | 1 | 12 | 1 | Языки 2 | 2 | 5 | 2 | PHP 3 | 3 | 4 | 3 | PHP7 4 | 8 | 11 | 2 | JS 5 | 9 | 10 | 3 | React 6 | 12 | 13 | 2 | HTML Теперь обновляю родителя: Код (Text): UPDATE language SET right_key = right_key + 2 WHERE right_key >= 5 AND left_key < 5; Код (Text): postgres=# select * FROM language; id | left_key | right_key | level | name ----+----------+-----------+-------+------- 3 | 3 | 4 | 3 | PHP7 4 | 8 | 11 | 2 | JS 5 | 9 | 10 | 3 | React 6 | 12 | 13 | 2 | HTML 1 | 1 | 14 | 1 | Языки 2 | 2 | 7 | 2 | PHP Добавляю подкатегорию с ключом 5 Код (Text): INSERT INTO language (level, left_key, right_key, name) VALUES (3, 5, 5+1, 'Laravel'); Вывожу и вижу, что всё работает, как надо Код (Text): ?column? | level ---------------+------- ..Языки | 1 ....PHP | 2 ......PHP7 | 3 ......Laravel | 3 ....JS | 2 ......React | 3 ....HTML | 2 (7 rows) Ищу дубликаты строк, если они есть, значит где-то произошла ошибка. Код (Text): SELECT left_key, right_key, COUNT(*) FROM language GROUP BY left_key, right_key HAVING COUNT(*) > 1;
Удаляю добавленный узел "Laravel" Узнаю, что у него левый ключ 5, а правый 6 Код (Text): DELETE FROM language WHERE left_key >= 5 AND right_key <= 6; Обновление родительской ветки (PHP) Код (Text): UPDATE language SET right_key = right_key - ( 6 - 5 + 1) WHERE right_key > 6 AND left_key < 5; Обновление последующих узлов Код (Text): UPDATE language SET left_key = left_key - ( 6 - 5 + 1 ), right_key = right_key - (6 - 5 + 1 ) WHERE left_key > 5; Если всё правильно сделано, то все ключи, должны сбросится в первоначальные значения, то есть должны быть такими же, как и при первом заполнении таблицы.