2012-02-13 5 views
3

У меня есть MySQL таблицы «папки»:Как рекурсивно удалять элементы из таблицы?

CREATE TABLE IF NOT EXISTS `folders` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `folder_key` varchar(40) NOT NULL, 
    `parent_key` varchar(40) NOT NULL, 
    `name` varchar(16) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB; 

Я не использовать целочисленные идентификаторы, только ключи (буквенно-цифровые хэши, которые я замещаются словами, чтобы сделать вещи более ясно). Таким образом, folder_key & parent_key Хеши SHA-1 (в моем реальном приложении).

INSERT INTO `folders` (`id`, `folder_key`, `parent_key`, `name`) VALUES 
(1, 'sun', 'root', '1'), 
(2, 'moon', 'sun', '1.1'), 
(3, 'jupiter', 'moon', '1.1.1'), 
(4, 'mars', 'root', '2'); 

Как вы видите, первый элемент имеет также родительскую клавишу, это корневой ключ.

Тестовый пример: Если я хочу, чтобы удалить элемент с folder_key === moon (1.1), она должна также удалить его детей элемент (ы), в данном случае это элемент с folder_key === jupiter (1.1.1) и так далее ...

Пусть говорят, что я хочу, чтобы удалить несколько элементов, так что я:

DELETE from folders WHERE folder_key IN('moon', 'mars'); После выполнения, таблица должна иметь только один элемент с folder_key === sun

Итак, вопрос в том, что: Как удалить элементы из этой таблицы, имеющие одну или несколько folder_keys (рекурсивно) с помощью триггеров MySQL, ON DELETE CASCADE или ...?

Спасибо.

ответ

3

С этой модели imposibble

  1. Вместо корня использования NULL, так что вы может использовать внешний ключ InnoDB + Cascade Delete.
  2. Вместо того чтобы использовать строку parent_key, используйте идентификатор (. Например, солнце = 1, луна = 2)

Другой способ заключается в изменении модели данных, так что вы можете Исли выбрать любой descendands из элемента - увидеть это, например, http://www.sitepoint.com/hierarchical-data-database-2/

3

Вы можете добавить FOREIGN KEY на folders с опцией CASCADE для УДАЛИТЬ:

ALTER TABLE `folders` ADD CONSTRAINT `FK_folder_parent` FOREIGN KEY `FK_folder_parent` (`parent_key`) 
REFERENCES `folders` (`folder_key`) 
ON DELETE CASCADE 
ON UPDATE CASCADE 

http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html

+0

mazzucci, ваш запрос не работает для меня (MySQL 5.5.9). – KenT

+0

Какая ошибка? Плохой синтаксис или у вас есть значения, которые не совпадают? Я вижу, что 'parent_key' NOT NULL? Вы должны сделать это NULL для корневых папок, не так ли? –

+0

большое спасибо. Я решил свою проблему, изменив модель. – KenT

2

Вместо того, чтобы хранить "родительский ключ" значение магазина их идентификатор

CREATE TABLE IF NOT EXISTS `folders` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `folder_key` varchar(40) NOT NULL, 
    `parent_key` int(11) NOT NULL, 
    `name` varchar(16) NOT NULL, 
    PRIMARY KEY (`id`) 
foreign key(`parent_key`) on delete cascade 
) ENGINE=InnoDB; 
0

@Naveen

вы должны использовать тот же datatypes при создании ограничения на удаление каскада. Теперь у вас есть unsigned int и подписанный int.

Смежные вопросы