Ответ 1
Если ваш каскад удаляет 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;
Таким образом, вы можете удалить продукт ИЛИ категорию, и только связанные записи в 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: "красные ботинки" и "красные пальто".
Удаление не будет каскадироваться дальше и не будет выводить категории "boots" и "coat".
комментарий:
вы по-прежнему не понимаете, как работают каскадные удаления. Они влияют только на таблицы, в которых определяется "на каскаде удаления". В этом случае каскад устанавливается в таблице "categories_products". Если вы удалите категорию "red", единственными записями, которые будут каскадировать delete в category_products, являются те, где category_id = red
. Он не будет касаться каких-либо записей, где "category_id = синий", и он не будет перемещаться вперед в таблицу "продукты", поскольку в этой таблице нет внешнего ключа.
Вот более конкретный пример:
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
нет внешнего ключа, поэтому каскад не будет работать там, поэтому у вас все еще есть ботинки и рукавицы. Там просто нет "синих сапог" и "синих рукавиц" больше.