Как работать с nested sets?

Рейтинг: 0Ответов: 1Опубликовано: 23.10.2014

Прошу не давать ссылки на статьи, так как они уже прочтены, и суть вопроса в тех моментах, которые я не понял.

Создал я таблицу:

    create table `category` not exists (
      `id` int(11) not null auto_increment,
      `name` varchar(255) not null,
      `left_key` int(11) not null,
      `right_key` int(11) not null,
      `level` int(11) not null default 0,
      primary key (`id`)
    ) engine=myisam default charset=utf8 auto_increment=1;

Далее сделал небольшой дамп:

insert into `category` (`name`, `level`) values
('Категория 1', 0),
('Категория 2', 0),
('Категория 3', 0),
('Подкатегория 1', 1),
('Подкатегория 2', 1),
('Подкатегория 3', 1),
('Подкатегория 1', 2),
('Подкатегория 2', 2),
('Подкатегория 3', 2),
('Подкатегория 4', 2),
('Подкатегория 5', 2),
('Подкатегория 1', 3),
('Подкатегория 2', 3),
('Подкатегория 3', 3),
('Подкатегория 1', 4),
('Подкатегория 2', 4),
('Подкатегория 3', 4);

Как теперь обновить левый и правый ключи? Буду благодарен за пояснение на доступном для рядового пользователя языке.

Ответы

▲ 1Принят

Ваш дамп не содержит информации о подчиненности узлов. Поэтому левый и правый ключ вы не обновите. И ключи надо обновлять при добавлении каждой записи, а не после того как...

Для каждого добавления узла вы можете самостоятельно выполнять несколько запросов (да, да в статье о них написано) подряд, либо добавлять данные такой процедурой:

CREATE PROCEDURE category_add(IN _parent int, IN _name varchar(150))
BEGIN
  declare $right_key, $level int;
  SELECT IFNULL(right_key,1),IFNULL(level,0) INTO $right_key,$level FROM category WHERE id = _parent;
  SET $right_key = IFNULL($right_key,1);
  SET $level = IFNULL($level,0);
  UPDATE category SET right_key = right_key + 2,  left_key = IF(left_key > $right_key, left_key + 2, left_key) WHERE right_key >= $right_key;
  INSERT INTO category (left_key,right_key,level,name) VALUES ($right_key, $right_key + 1, $level + 1,_name);
END

Фидл.