Om din cascading raderar nuke en produkt eftersom den var medlem i en kategori som dödades, då har du ställt in dina främmande nycklar på ett felaktigt sätt. Med tanke på dina exempeltabeller bör du ha följande tabelluppsättning:
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å så sätt kan du ta bort en produkt ELLER en kategori, och bara de associerade posterna i kategorier_produkter kommer att dö vid sidan av. Kaskaden går inte längre upp i trädet och raderar den överordnade produkten/kategoritabellen.
t.ex.
products: boots, mittens, hats, coats
categories: red, green, blue, white, black
prod/cats: red boots, green mittens, red coats, black hats
Om du tar bort den "röda" kategorin dör bara den "röda" posten i kategoritabellen, liksom de två posterna prod/cats:"röda stövlar" och "röda rockar".
Borttagningen kommer inte att falla längre och tar inte bort kategorierna "stövlar" och "rockar".
kommentarsuppföljning:
du missförstår fortfarande hur kaskadraderingar fungerar. De påverkar bara de tabeller där "vid raderingskaskaden" är definierad. I det här fallet sätts kaskaden i tabellen "kategorier_produkter". Om du tar bort den "röda" kategorin är de enda poster som kommer att raderas i cascades_products de där category_id = red
. Den kommer inte att röra några poster där 'category_id =blue' och den skulle inte gå vidare till tabellen "products", eftersom det inte finns någon främmande nyckel definierad i den tabellen.
Här är ett mer konkret exempel:
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
+------------+-------------+
Låt oss säga att du tar bort kategori #2 (blå):
DELETE FROM categories WHERE (id = 2);
DBMS kommer att titta på alla tabeller som har en främmande nyckel som pekar på 'kategorier'-tabellen, och raderar de poster där det matchande id är 2. Eftersom vi bara definierade den främmande nyckelrelationen i products_categories
, du får den här tabellen när raderingen är klar:
+------------+-------------+
| product_id | category_id |
+------------+-------------+
| 1 | 1 | // red mittens
| 2 | 1 | // red boots
+------------+-------------+
Det finns ingen främmande nyckel definierad i products
bord, så att kaskaden inte fungerar där, så du har fortfarande stövlar och vantar listade. Det finns bara inga "blå stövlar" och inga "blå vantar" längre.