Se il tuo cascading elimina il nuke di un prodotto perché apparteneva a una categoria che è stata uccisa, allora hai impostato le tue chiavi esterne in modo errato. Date le vostre tabelle di esempio, dovreste avere la seguente configurazione della tabella:
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;
In questo modo, puoi eliminare un prodotto O una categoria e solo i record associati in categorie_prodotti moriranno insieme. La cascata non si sposterà più in alto sull'albero ed eliminerà la tabella del prodotto / categoria principale.
per esempio
products: boots, mittens, hats, coats
categories: red, green, blue, white, black
prod/cats: red boots, green mittens, red coats, black hats
Se elimini la categoria 'rosso', allora muore solo la voce 'rossa' nella tabella delle categorie, così come le due voci prod / cats: 'stivali rossi' e 'cappotti rossi'.
L'eliminazione non scenderà più a cascata e non eliminerà le categorie "stivali" e "cappotti".
follow-up commento:
stai ancora fraintendendo come funzionano le eliminazioni in cascata. Hanno effetto solo sulle tabelle in cui è definito "on delete cascade". In questo caso, la cascata è impostata nella tabella "categorie_prodotti". Se si elimina la categoria "rossa", gli unici record che verranno eliminati in cascata in categorie_prodotti sono quelli in cui category_id = red
. Non toccherà alcun record in cui 'category_id = blue', e non si sposterà in avanti alla tabella "prodotti", perché non esiste una chiave esterna definita in quella tabella.
Ecco un esempio più concreto:
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
+------------+-------------+
Supponiamo che tu elimini la categoria # 2 (blu):
DELETE FROM categories WHERE (id = 2);
il DBMS esaminerà tutte le tabelle che hanno una chiave esterna che punta alla tabella 'categorie' ed eliminerà i record in cui l'id corrispondente è 2. Poiché abbiamo definito la relazione di chiave esterna solo products_categories
, si finisce con questa tabella una volta che l'eliminazione completa:
+------------+-------------+
| product_id | category_id |
+------------+-------------+
| 1 | 1 | // red mittens
| 2 | 1 | // red boots
+------------+-------------+
Non c'è una chiave esterna definita nella products
tabella, quindi la cascata non funzionerà lì, quindi hai ancora stivali e guanti elencati. Non ci sono più "stivali blu" e "guanti blu".