Hvis din cascading sletter nuke et produkt, fordi det var medlem af en kategori, der blev dræbt, så har du konfigureret dine fremmednøgler forkert. Givet dine eksempeltabeller bør du have følgende tabelopsætning:
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;
På denne måde kan du slette et produkt ELLER en kategori, og kun de tilknyttede poster i kategorier_produkter vil dø ved siden af. Kaskaden vil ikke rejse længere op i træet og slette den overordnede produkt-/kategoritabell.
f.eks.
products: boots, mittens, hats, coats
categories: red, green, blue, white, black
prod/cats: red boots, green mittens, red coats, black hats
Hvis du sletter den 'røde' kategori, dør kun den 'røde' post i kategoritabellen, samt de to poster prod/cats:'røde støvler' og 'røde frakker'.
Sletningen vil ikke kaskade længere og vil ikke fjerne kategorierne 'støvler' og 'frakker'.
kommentaropfølgning:
du misforstår stadig, hvordan kaskadede sletninger fungerer. De påvirker kun de tabeller, hvor "ved slette-kaskaden" er defineret. I dette tilfælde indstilles kaskaden i tabellen "kategorier_produkter". Hvis du sletter den "røde" kategori, er de eneste poster, der vil kaskadeslette i categories_products, dem, hvor category_id = red
. Den vil ikke røre nogen poster, hvor 'category_id =blue', og den vil ikke gå videre til tabellen "produkter", fordi der ikke er defineret nogen fremmednøgle i den tabel.
Her er et mere konkret eksempel:
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
+------------+-------------+
Lad os sige, at du sletter kategori #2 (blå):
DELETE FROM categories WHERE (id = 2);
DBMS vil se på alle de tabeller, som har en fremmednøgle, der peger på 'kategorier'-tabellen, og slette de poster, hvor det matchende id er 2. Da vi kun definerede fremmednøglerelationen i products_categories
, ender du med denne tabel, når sletningen er fuldført:
+------------+-------------+
| product_id | category_id |
+------------+-------------+
| 1 | 1 | // red mittens
| 2 | 1 | // red boots
+------------+-------------+
Der er ingen fremmednøgle defineret i products
bord, så vil kaskaden ikke fungere der, så du har stadig støvler og vanter listet. Der er bare ingen 'blå støvler' og ingen 'blå vanter' længere.