Якщо ваш каскад видаляє продукт nuke, тому що він входив до категорії вбитої категорії, значить, ви встановили свої зовнішні ключі неправильно. З огляду на ваші приклади таблиць, ви повинні мати таку настройку таблиці:
CREATE TABLE categories (
id int unsigned not null primary key,
name VARCHAR(255) default null
)Engine=InnoDB;
CREATE TABLE products (
id int unsigned not null primary key,
name VARCHAR(255) default null
)Engine=InnoDB;
CREATE TABLE categories_products (
category_id int unsigned not null,
product_id int unsigned not null,
PRIMARY KEY (category_id, product_id),
KEY pkey (product_id),
FOREIGN KEY (category_id) REFERENCES categories (id)
ON DELETE CASCADE
ON UPDATE CASCADE,
FOREIGN KEY (product_id) REFERENCES products (id)
ON DELETE CASCADE
ON UPDATE CASCADE
)Engine=InnoDB;
Таким чином, ви можете видалити продукт АБО категорію, і поряд із цим загинуть лише пов’язані записи в категорії_продукти. Каскад не переміститься далі по дереву та видалить таблицю батьківського продукту / категорії.
напр
products: boots, mittens, hats, coats
categories: red, green, blue, white, black
prod/cats: red boots, green mittens, red coats, black hats
Якщо ви видалите категорію "червоний", вмирає лише запис "червоний" у таблиці категорій, а також два записи prod / cats: "червоні чоботи" та "червоні шуби".
Видалення не буде наближатись далі і не виведе категорії "чоботи" та "пальто".
подальший коментар:
ви все ще не розумієте, як працюють каскадні видалення. Вони впливають лише на таблиці, в яких визначено "каскад видалення". У цьому випадку каскад встановлюється в таблиці "категорії_продукти". Якщо ви видалите категорію "червоний", лише записи, які будуть каскадно видаляти, у категоріях_продуктів - це ті, де category_id = red
. Він не торкнеться жодного запису, де 'category_id = blue', і він не переміщуватиметься до таблиці "товари", оскільки в цій таблиці немає жодного зовнішнього ключа.
Ось більш конкретний приклад:
categories: products:
+----+------+ +----+---------+
| id | name | | id | name |
+----+------+ +----+---------+
| 1 | red | | 1 | mittens |
| 2 | blue | | 2 | boots |
+---++------+ +----+---------+
products_categories:
+------------+-------------+
| product_id | category_id |
+------------+-------------+
| 1 | 1 | // red mittens
| 1 | 2 | // blue mittens
| 2 | 1 | // red boots
| 2 | 2 | // blue boots
+------------+-------------+
Скажімо, ви видалите категорію №2 (синій):
DELETE FROM categories WHERE (id = 2);
СУБД перегляне всі таблиці, які мають зовнішній ключ, що вказує на таблицю "категорії", і видалить записи, де відповідає ідентифікаційний номер 2. Оскільки ми визначали лише взаємозв'язок із зовнішнім ключем products_categories
, ви закінчуєте цю таблицю, як тільки видалити завершує:
+------------+-------------+
| product_id | category_id |
+------------+-------------+
| 1 | 1 | // red mittens
| 2 | 1 | // red boots
+------------+-------------+
У products
таблиці немає жодного закордонного ключа , тому каскад там не працюватиме, тому у вас все ще є перелічені чоботи та рукавиці. Просто немає «блакитних черевиків» і «синіх рукавиць» більше.