Mysql
 sql >> Database >  >> RDS >> Mysql

Vincoli della chiave esterna MySQL, eliminazione a cascata

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".