Se la tua cascata cancella un prodotto nucleare perché era un membro di una categoria che è stata uccisa, allora hai impostato le tue chiavi esterne in modo errato. Date le tue tabelle di esempio, dovresti 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 OPPURE una categoria e solo i record associati in categorie_prodotti moriranno insieme. La cascata non si sposterà più in alto nell'albero ed eliminerà la tabella prodotto/categoria padre.
es.
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', muore solo la voce 'rossa' nella tabella delle categorie, così come le due voci prod/cats:'stivali rossi' e 'cappotti rossi'.
L'eliminazione non si estenderà ulteriormente e non eliminerà le categorie "stivali" e "cappotti".
follow-up dei commenti:
stai ancora fraintendendo come funzionano le eliminazioni a cascata. Influiscono solo sulle tabelle in cui è definita la "cascata di eliminazione". In questo caso, la cascata è impostata nella tabella "categories_products". Se elimini la categoria "rossa", gli unici record che verranno eliminati a cascata in categorie_prodotti sono quelli in cui category_id = red
. Non toccherà alcun record in cui 'category_id =blue' e non passerà alla tabella "products", perché non c'è 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 di eliminare la categoria n. 2 (blu):
DELETE FROM categories WHERE (id = 2);
il DBMS esaminerà tutte le tabelle che hanno una chiave esterna che punta alla tabella "categories" ed eliminerà i record in cui l'ID corrispondente è 2. Poiché abbiamo definito solo la relazione della chiave esterna in products_categories
, ti ritroverai con questa tabella una volta completata l'eliminazione:
+------------+-------------+
| product_id | category_id |
+------------+-------------+
| 1 | 1 | // red mittens
| 2 | 1 | // red boots
+------------+-------------+
Non esiste una chiave esterna definita nei products
tabella, quindi la cascata non funzionerà lì, quindi hai ancora stivali e guanti elencati. Non ci sono più "stivali blu" e nemmeno "guanti blu".