Si su eliminación en cascada elimina un producto nuclear porque era miembro de una categoría que fue eliminada, entonces ha configurado incorrectamente sus claves foráneas. Dadas sus tablas de ejemplo, debe tener la siguiente configuración de tabla:
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;
De esta manera, puede eliminar un producto O una categoría, y solo los registros asociados en categories_products morirán junto. La cascada no viajará más arriba en el árbol y eliminará la tabla de producto / categoría principal.
p.ej
products: boots, mittens, hats, coats
categories: red, green, blue, white, black
prod/cats: red boots, green mittens, red coats, black hats
Si elimina la categoría 'rojo', entonces solo la entrada 'roja' en la tabla de categorías muere, así como las dos entradas prod / cats: 'botas rojas' y 'abrigos rojos'.
La eliminación no seguirá en cascada y no eliminará las categorías 'botas' y 'abrigos'.
comentario de seguimiento:
todavía no entiendes cómo funcionan las eliminaciones en cascada. Solo afectan a las tablas en las que se define "on delete cascade". En este caso, la cascada se establece en la tabla "categories_products". Si elimina la categoría 'roja', los únicos registros que se eliminarán en cascada en category_products son aquellos donde category_id = red
. No tocará ningún registro donde 'category_id = blue', y no viajará a la tabla de "productos", porque no hay una clave externa definida en esa tabla.
Aquí hay un ejemplo más 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
+------------+-------------+
Digamos que eliminas la categoría # 2 (azul):
DELETE FROM categories WHERE (id = 2);
el DBMS examinará todas las tablas que tienen una clave externa que apunta a la tabla de 'categorías' y eliminará los registros donde la identificación coincidente es 2. Dado que solo definimos la relación de clave externa products_categories
, terminará con esta tabla una vez que eliminar completa:
+------------+-------------+
| product_id | category_id |
+------------+-------------+
| 1 | 1 | // red mittens
| 2 | 1 | // red boots
+------------+-------------+
No hay una clave foránea definida en la products
tabla, por lo que la cascada no funcionará allí, por lo que todavía tiene botas y guantes enumerados. Ya no hay 'botas azules' ni 'guantes azules'.