Если ваш каскад удаляет ядерный продукт, потому что он был членом убитой категории, то вы неправильно настроили свои внешние ключи. Учитывая ваши примеры таблиц, вы должны иметь следующую настройку таблицы:
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;
Таким образом, вы можете удалить продукт ИЛИ категорию, и только связанные записи в category_products умрут вместе с ним. Каскад не пройдет дальше по дереву и не удалит родительскую таблицу товаров / категорий.
например
products: boots, mittens, hats, coats
categories: red, green, blue, white, black
prod/cats: red boots, green mittens, red coats, black hats
Если вы удалите «красную» категорию, то умирает только «красная» запись в таблице категорий, а также две записи prod / cats: «красные сапоги» и «красные пальто».
Удаление не будет касаться дальше и не удалит категории «ботинки» и «пальто».
продолжение комментария:
Вы все еще не понимаете, как работает каскадное удаление. Они влияют только на таблицы, в которых определен «каскад удаления». В этом случае каскад устанавливается в таблице «category_products». Если вы удалите «красную» категорию, единственными записями, которые будут каскадно удаляться в category_products, являются те, где category_id = red
. Он не будет касаться записей, где «category_id = blue», и не будет перемещаться дальше к таблице «products», потому что в этой таблице не определен внешний ключ.
Вот более конкретный пример:
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
таблице не определен внешний ключ , поэтому каскад не будет работать там, поэтому у вас все еще есть ботинки и рукавицы. Просто больше нет «синих сапог» и «синих варежек».