Si su cascada elimina un producto nuclear porque era un miembro de una categoría que se eliminó, entonces ha configurado sus claves externas incorrectamente. Teniendo en cuenta sus tablas de ejemplo, debe tener la siguiente configuración de la 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 sólo los registros asociados en categories_products morirán junto. La cascada no viajará más arriba en el árbol y eliminará la tabla de productos/categorías principales.
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 de 'rojo', entonces sólo la entrada 'rojo' en la tabla de categorías troqueles, así como las dos entradas prod/gatos: 'botas rojas' y 'chaquetas rojas'.
La eliminación no seguirá en cascada y no eliminará las categorías 'botas' y 'capas'.
comentario seguimiento:
todavía estás malentendido cómo cascada elimina el trabajo. Solo afectan 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 'rojo', los únicos registros que eliminarán en cascada en categorías_productos son aquellos en los que category_id = red
. No tocará ningún registro donde 'category_id = blue', y no irá 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 se elimina la categoría # 2 (azul):
DELETE FROM categories WHERE (id = 2);
el DBMS se verá en todas las mesas que tienen un señalador clave externa en la tabla de "categorías", y eliminar los registros donde el ID coincidente es 2. Dado que solo definimos la relación de clave externa en products_categories
, termina con esta tabla una vez que se completa la eliminación:
+------------+-------------+
| product_id | category_id |
+------------+-------------+
| 1 | 1 | // red mittens
| 2 | 1 | // red boots
+------------+-------------+
No hay una clave externa definida en la tabla products
, por lo que la cascada no funcionará allí, por lo que todavía tiene botas y mitones en la lista. Ya no hay 'botas azules' ni más 'mitones azules'.
Hi - es posible que desee modificar el título de la pregunta, se trata de eliminaciones en cascada en realidad, no específicamente tablas pivote. – Paddyslacker