Использование модели вложенного набора для хранения иерархических данных в SQLite, как я могу переместить категорию в другую категорию

Я пытаюсь хранить иерархические данные с использованием SQLite. После долгих поисков я решил использовать модель вложенного множества вместо список смежности, потому что почти 90% операций будут считаны и только 10% будут обновлены / удалены / созданы.

Я последовал этому примеру:
http://www.phpro.org/tutorials/Managing-Hierarchical-Data-with-PHP-and-MySQL.html

И это прекрасно работает для добавления, удаления и чтения новых узлов.

Но я не нашел ни одной статьи, объясняющей, как обновить дерево, например, перемещение категории в другую категорию.

Ниже моя структура базы данных:

id   name   left_node   right_node
1    name1     1          2

** Я не нашел места, объясняющего, как обновить иерархию, которая мне действительно нужна. **

Еще одна проблема

public function delete_node($pleft, $pright){

$width = $pright-$pleft+1;

$delete_sql = "delete from categories where left_node between $pleft and $pright";
$update_sql1 = "update categories set right_node = right_node-$width where right_node > $pright";
$update_sql2 = "update categories set left_node = left_node-$width where left_node> $pright";
//
$this->db->trans_start();
//
$this->db->query($delete_sql);

//
$this->db->query($update_sql1);
$this->db->query($update_sql2);
$this->db->trans_complete();
//
return $this->db->trans_status();
}

Это мой метод удаления, и для его завершения требуется 30 мс. Это нормально?

Я решил проблему, спасибо за помощь
http://www.ninthavenue.com.au/how-to-move-a-node-in-nested-sets-with-sql

Я использую codeigniter с базой данных sqlite.
ниже моя функция,

public function move_node($pleft, $pright, $origin_left_pos, $origin_right_pos){

//
//the new_left_position is different according to which way you want to move the node
$new_left_position = $pleft + 1;
//
$width = $origin_right_pos - $origin_left_pos + 1;
$temp_left_position = $origin_left_pos;

$distance = $new_left_position - $origin_left_pos;
//backwards movement must account for new space
if($distance < 0){

$distance -= $width;
$temp_left_position += $width;

}
//
$update_sql1 = "update categories set left_node = left_node+$width where left_node >=  $new_left_position";

$update_sql2 = "update categories set right_node = right_node+$width where right_node >= $new_left_position";

//
$update_sql3 = "update categories set left_node = left_node+$distance , right_node = right_node+$distance where left_node >= $temp_left_position AND right_node < $temp_left_position+$width";

//
$update_sql4 = "update categories set left_node = left_node-$width where left_node > $origin_right_pos";
$update_sql5 = "update categories set right_node = right_node-$width where right_node > $origin_right_pos";

//

$this->db->trans_start();

$this->db->query($update_sql1);

//
$this->db->query($update_sql2);
$this->db->query($update_sql3);
$this->db->query($update_sql4);
$this->db->query($update_sql5);
$this->db->trans_complete();

return $this->db->trans_status();
}

3

Решение

В SO есть пара ответов именно о вашей проблеме:

Переместить узел во вложенном множестве

Переместить узел в дереве вложенных множеств

Что касается времени, которое занимает ваш метод удаления, 30 мс — это очень мало для такого рода операций, так что вам не о чем беспокоиться. Не попасть в ловушку преждевременная оптимизация. 🙂

1

Другие решения

Других решений пока нет …