— помечаем переносимый узел и детей fix = 1
— нормализуем ключи для узлов, которые находятся после удаляемого (как при удалении)
— изменяем ключи для переносимого узла и детей
— нормализуем ключи после переносимого узла (как при добавлении)
— снимаем пометку fix = 0 для всех
Введение дополнительной колонки облегчает понимание задачи. Флаг по сути помечает временно удалённые узлы.
Добавь ещё одно индексное поле с md5(все данные таблицы) и при проверке на дубль сравнивай хеши.
SELECT 1 FROM table WHERE hash='5c331a6790ba2d61a5c372336c9d215e'