Ако каскадирането ви изтрие ядрен продукт, защото е бил член на категория, която е била убита, значи сте настроили външните си ключове неправилно. Като се имат предвид вашите примерни таблици, трябва да имате следната настройка на таблицата:
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:„червени ботуши“ и „червени палта“.
Изтриването няма да продължи по-нататък и няма да премахне категориите „ботуши“ и „палта“.
последващ коментар:
все още не разбирате как работят каскадно изтриване. Те засягат само таблиците, в които е дефинирана "каскадата за изтриване". В този случай каскадата се задава в таблицата "categories_products". Ако изтриете категорията „червено“, единствените записи, които ще изтриват каскадно в категории_продукти, са тези, където 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);
СУБД ще разгледа всички таблици, които имат външен ключ, сочещ към таблицата 'categories', и ще изтрие записите, където съответстващият идентификатор е 2. Тъй като ние дефинирахме връзката на външния ключ само в products_categories
, в крайна сметка получавате тази таблица, след като изтриването завърши:
+------------+-------------+
| product_id | category_id |
+------------+-------------+
| 1 | 1 | // red mittens
| 2 | 1 | // red boots
+------------+-------------+
В products
няма дефиниран външен ключ маса, така че каскадата няма да работи там, така че все още имате изброени ботуши и ръкавици. Вече просто няма „сини ботуши“ и „сини ръкавици“.