Se il collegamento a cascata elimina un prodotto a causa di un membro di una categoria che è stato ucciso, le chiavi esterne sono state configurate in modo errato. Dato il tuo esempio tabelle, si dovrebbe avere la seguente impostazione 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, è possibile eliminare un prodotto o di una categoria, e solo i record associati a categories_products moriranno insieme. La cascata non si sposta più in alto sull'albero ed elimina la tabella prodotto/categoria padre.
ad es.
products: boots, mittens, hats, coats
categories: red, green, blue, white, black
prod/cats: red boots, green mittens, red coats, black hats
Se si elimina la categoria 'rosso', poi solo la voce 'rosso' nella tabella categorie muore, così come le due voci prod/gatti: 'stivali rossi' e 'giubbe rosse'.
L'eliminazione non si sovrapporrà ulteriormente e non eliminerà le categorie "stivali" e "cappotti".
commento followup:
stai ancora equivoco come cascata elimina il lavoro. Hanno effetto solo sulle tabelle in cui è definito "on delete cascade". In questo caso, la cascata viene impostata nella tabella "categories_products". Se elimini la categoria "rossa", gli unici record che verranno eliminati a cascata in categories_products sono quelli in cui category_id = red
. Non toccherà alcun record in cui 'category_id = blue', e non viaggerà verso la tabella "prodotti", perché non ci sono chiavi esterne definite 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
+------------+-------------+
Diciamo che si elimina categoria # 2 (blu):
DELETE FROM categories WHERE (id = 2);
il DBMS esaminerà tutti i tavoli che hanno una punta chiave esterna a la tabella "categorie" ed elimina i record in cui l'ID corrispondente è 2. Poiché abbiamo definito la relazione di chiave esterna solo in products_categories
, si finisce con questa tabella una volta completata l'eliminazione:
+------------+-------------+
| product_id | category_id |
+------------+-------------+
| 1 | 1 | // red mittens
| 2 | 1 | // red boots
+------------+-------------+
Non c'è chiave esterna definita nella tabella products
, quindi la cascata non funziona lì, così hai ancora stivali e guanti elencati. Non ci sono più "stivali blu" e "muffole blu".
Hi - si potrebbe desiderare di modificare il titolo della domanda, si tratta di cascata elimina in realtà, non in particolare tabelle pivot. – Paddyslacker