Si votre mise en cascade supprime l'arme nucléaire d'un produit parce qu'il faisait partie d'une catégorie qui a été tuée, c'est que vous avez mal configuré vos clés étrangères. Compte tenu de vos exemples de tables, vous devriez avoir la configuration de table suivante:
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;
De cette façon, vous pouvez supprimer un produit OU une catégorie, et seuls les enregistrements associés dans categories_products mourront à côté. La cascade ne se déplacera pas plus haut dans l'arborescence et supprimera la table de produits / catégories parent.
par exemple
products: boots, mittens, hats, coats
categories: red, green, blue, white, black
prod/cats: red boots, green mittens, red coats, black hats
Si vous supprimez la catégorie «rouge», alors seule l'entrée «rouge» dans le tableau des catégories meurt, ainsi que les deux entrées prod / cats: «red boots» et «red coats».
La suppression ne se répercutera pas plus loin et ne supprimera pas les catégories «bottes» et «manteaux».
suivi des commentaires:
vous ne comprenez toujours pas comment fonctionnent les suppressions en cascade. Ils n'affectent que les tables dans lesquelles la "cascade à la suppression" est définie. Dans ce cas, la cascade est définie dans le tableau "categories_products". Si vous supprimez la catégorie «rouge», les seuls enregistrements qui seront supprimés en cascade dans categories_products sont ceux où category_id = red
. Il ne touchera aucun enregistrement où 'category_id = blue', et il ne se déplacera pas vers la table "products", car il n'y a pas de clé étrangère définie dans cette table.
Voici un exemple plus concret:
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
+------------+-------------+
Disons que vous supprimez la catégorie # 2 (bleu):
DELETE FROM categories WHERE (id = 2);
le SGBD examinera toutes les tables qui ont une clé étrangère pointant vers la table 'categories', et supprimera les enregistrements où l'ID correspondant est 2. Puisque nous n'avons défini la relation de clé étrangère que dans products_categories
, vous vous retrouvez avec cette table une fois le la suppression est terminée:
+------------+-------------+
| product_id | category_id |
+------------+-------------+
| 1 | 1 | // red mittens
| 2 | 1 | // red boots
+------------+-------------+
Il n'y a pas de clé étrangère définie dans le products
tableau, donc la cascade ne fonctionnera pas là-bas, donc vous avez toujours des bottes et des mitaines répertoriées. Il n'y a plus de «bottes bleues» ni de «mitaines bleues».