Mysql Внешний ключ

udodirc

Новичок
Здраствуйте, есть вопрос.
Вот есть допустим таблица `category`
В этой таблице три поля id, parent_id, name.

Вопрос: могули я создать внешний ключ parent_id таблицы `category` на поле id той же таблицы`category`.
 

udodirc

Новичок
можешь,сделай его только NULL по умолчанию
--
-- Table structure for table `category`
--

CREATE TABLE IF NOT EXISTS `category` (
`id` int(8) NOT NULL AUTO_INCREMENT,
`parent_id` int(8) DEFAULT NULL,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`),
KEY `parent_id` (`parent_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;

--
-- Dumping data for table `category`
--

INSERT INTO `category` (`id`, `parent_id`, `name`) VALUES
(1, NULL, 'Цветы'),
(2, 1, 'Розы');

--
-- Constraints for dumped tables
--

--
-- Constraints for table `category`
--
ALTER TABLE `category`
ADD CONSTRAINT `category` FOREIGN KEY (`parent_id`) REFERENCES `category` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
[/PHP]

Создал таблицу, если меняю id родительской записи пишет:

#1451 - Cannot delete or update a parent row: a foreign key constraint fails (`test2`.`category`, CONSTRAINT `category` FOREIGN KEY (`parent_id`) REFERENCES `category` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)
 

udodirc

Новичок
Тут такая ситуация.
Я хочу сделать так, чтобы при удаление раздела допустим id 5, удалялись автоматом все его подразделы у кого стоят parent_id = 5.
Зачем? Есть еще таблица products, она связана с таблицей category по внешнему ключу.
Когда удаляется категоряи под id 5, то удаляются все значение в таблице продукты по внешнему ключу, плюс все подразделы где parent_id = 5.
То есть я хочу удалить одним действием все подчиненые записи.
 

Redjik

Джедай-мастер
Ну это понятно, ну судя по DDL все правильно у тебя.

UPD. но сильно такими штуками не увлекайся все равно. Я сам так делаю, но далеко не везде. Представь ситуацию, что у тебя есть еще галерея изображений, для каждой категории.
То есть - категория носки, и ты хочешь в галерее в категории показать не только картинку носков, но и фабрику... и .т.п. Логично, что изображения будут has_many для категории.
Ты так же ставишь на таблицу ON DELETE CASCADE, но сами файлы изображений у тебя будут оставаться на диске.
 

Ярослав

Новичок
Тут такая ситуация.
Когда удаляется категоряи под id 5, то удаляются все значение в таблице продукты по внешнему ключу, плюс все подразделы где parent_id = 5.
То есть я хочу удалить одним действием все подчиненые записи.
Очень опасное действие, т.к. будут удаляться еще и продукты тех категорий, где parent_id = 5 и если у них есть паренты то рекурсивно.
Так можно и всю базу грохнуть.
 

udodirc

Новичок
Очень опасное действие, т.к. будут удаляться еще и продукты тех категорий, где parent_id = 5 и если у них есть паренты то рекурсивно.
Так можно и всю базу грохнуть.
Так мне это и надо, чтобы в скрипте все рекурсивно не удалять, одно действие и все. Плюс еще целостность базы сохраняется, а не так, часть удалилась, а часть мусором лежит.
 

Redjik

Джедай-мастер
ты не учел секретарш...
они тебе базу навернут в течение недели - проверено
 

udodirc

Новичок
ты не учел секретарш...
они тебе базу навернут в течение недели - проверено
С другой стороны если я удаляю раздел то, мне надо удалить подчиненные разделы и товары в них.
Там вообще проверка стоит, если есть подчиненые разделыи и товары в них, то удаление невозможно. Это на всякий случай, чтобы мусора в базе не было.
Я знаю что так структур базы и планируют, чтобы целостность сохранить.
 

Redjik

Джедай-мастер
ну дак ты скажи наконец, что получилось, а что нет =)
 

Ярослав

Новичок
udodirc
Это не есть хорошо!

Нужно делать ключами на уровне базы!
Сначала настраиваешь ключи, а потом, псевдокод:
PHP:
BEGIN TRANSACTION
try {
   DELETE FROM....

   COMMIT
   // категории с подкатегориями (если были) успешно удалены
} catch(DbException $e)
{
   ROLLBACK
   // есть зависимости в категории или в подкатегориях на продукты
}
Пока не настроишь таблицу категорий, дальше двигаться нельзя.
Какие там ключи есть?
И давай сюда SQL UPDATE запроса
 

Redjik

Джедай-мастер
Спорим ты сам тупишь =)
У меня твой пример работает правильно.
Скорее всего ты пытаешься наначить parent_id - id текущей записи...
Создай еще пару записей и поиграйся с ними...

дубль два - у меня твой пример работает.
 

Redjik

Джедай-мастер
Ярослав
С одной стороны это верно, но я не вижу ничего плохо, разруливать все на уровне модели в php.

В yii есть куча точек наблюдателей, поэтому с AR очень удобно контролировать изменения в базе и вести лог.
 

Ярослав

Новичок
Redjik
Абсолютно с этим согласен.
Тогда в данном случаи я бы логику удаления выносил тоже в php, подчищая при этом картинки для продуктов, связанные категории и т.д.
А сама категория была бы обьектом с методом delete
 

Redjik

Джедай-мастер
Ярослав
мне иногда лень для many_many выносить в php =) Минус мне в карму =)))
 
Сверху