sql >> Databasteknik >  >> RDS >> Mysql

MySQL främmande nyckel begränsningar, kaskad radering

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.



  1. Hur Atanh() fungerar i PostgreSQL

  2. Vad är nytt i PgBouncer 1.6

  3. Inaktivera rotinloggning i phpMyAdmin

  4. Hur man felsöker MySQL-definieringsproblem