Mysql
 sql >> база данни >  >> RDS >> Mysql

MySQL ограничения на външния ключ, каскадно изтриване

Ако каскадирането ви изтрие ядрен продукт, защото е бил член на категория, която е била убита, значи сте настроили външните си ключове неправилно. Като се имат предвид вашите примерни таблици, трябва да имате следната настройка на таблицата:

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;

По този начин можете да изтриете продукт ИЛИ категория и само свързаните записи в категории_продукти ще умрат заедно. Каскадата няма да се движи по-нагоре по дървото и да изтрие родителската таблица с продукти/категории.

напр.

products: boots, mittens, hats, coats
categories: red, green, blue, white, black

prod/cats: red boots, green mittens, red coats, black hats

Ако изтриете категорията „червени“, тогава само записът „червен“ в таблицата с категории умира, както и двата записа prod/cats:„червени ботуши“ и „червени палта“.

Изтриването няма да продължи по-нататък и няма да премахне категориите „ботуши“ и „палта“.

последващ коментар:

все още не разбирате как работят каскадно изтриване. Те засягат само таблиците, в които е дефинирана "каскадата за изтриване". В този случай каскадата се задава в таблицата "categories_products". Ако изтриете категорията „червено“, единствените записи, които ще изтриват каскадно в категории_продукти, са тези, където category_id = red . Той няма да докосне записи, където 'category_id =blue', и няма да пътува нататък към таблицата "продукти", тъй като в тази таблица няма дефиниран външен ключ.

Ето по-конкретен пример:

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
+------------+-------------+

Да приемем, че изтривате категория №2 (синьо):

DELETE FROM categories WHERE (id = 2);

СУБД ще разгледа всички таблици, които имат външен ключ, сочещ към таблицата 'categories', и ще изтрие записите, където съответстващият идентификатор е 2. Тъй като ние дефинирахме връзката на външния ключ само в products_categories , в крайна сметка получавате тази таблица, след като изтриването завърши:

+------------+-------------+
| product_id | category_id |
+------------+-------------+
| 1          | 1           | // red mittens
| 2          | 1           | // red boots
+------------+-------------+

В products няма дефиниран външен ключ маса, така че каскадата няма да работи там, така че все още имате изброени ботуши и ръкавици. Вече просто няма „сини ботуши“ и „сини ръкавици“.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да експортирате mysql база данни с помощта на командния ред?

  2. В SQL добре ли е две таблици да се отнасят една към друга?

  3. Проблем с Java + Mysql UTF8

  4. Как мога да се присъединя към множество SQL таблици, използвайки идентификаторите?

  5. Урок за архивиране и възстановяване (експортиране и импортиране) на MySQL бази данни