Si votre cascade supprime un produit parce qu'il appartenait à une catégorie qui a été supprimée, vous n'avez pas correctement configuré vos clés étrangères. Compte tenu de vos tables d'exemple, vous devriez avoir la configuration du tableau suivant:
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 que les enregistrements associés à categories_products vont mourir à côté. La cascade ne se déplace pas plus loin dans l'arborescence et supprime la table de produits/catégories parente.
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 que l'entrée « rouge » dans le tableau des catégories meurt, ainsi que les deux entrées prod/chats: « bottes rouges » et les « tuniques rouges ».
La suppression ne cascade pas plus loin et ne supprime pas les catégories «bottes» et «manteaux».
commentaire suivi:
vous malentendu encore comment supprime le travail en cascade. Ils affectent uniquement les tables dans lesquelles "on delete cascade" est défini. Dans ce cas, la cascade est définie dans la table "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 sera pas redirigé 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 se penchera sur toutes les tables qui ont une clé étrangère pointant à la table 'categories', et supprimez les enregistrements où l'ID correspondant est 2. Puisque nous avons seulement défini la relation de clé étrangère dans products_categories
, vous vous retrouvez avec cette table une fois la suppression 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 la table products
, donc la cascade ne fonctionnera pas là, donc vous avez toujours des bottes et des mitaines listées. Il n'y a plus de 'bottes bleues' et plus de 'mitaines bleues'.
Salut - vous pouvez modifier le titre de la question, il est à propos de la cascade supprime vraiment, pas tables pivotantes spécifiquement. – Paddyslacker