Se sua cascata excluir um produto nuke porque ele era um membro de uma categoria que foi eliminada, você configurou suas chaves estrangeiras incorretamente. Dadas as tabelas de exemplo, você deve ter a seguinte configuração de tabela:
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;
Dessa forma, você pode excluir um produto OU uma categoria e apenas os registros associados em categories_products morrerão ao lado. A cascata não viajará mais longe na árvore e excluirá a tabela de produto / categoria pai.
por exemplo
products: boots, mittens, hats, coats
categories: red, green, blue, white, black
prod/cats: red boots, green mittens, red coats, black hats
Se você excluir a categoria 'vermelho', apenas a entrada 'vermelho' na tabela de categorias morre, bem como as duas entradas prod / cats: 'botas vermelhas' e 'casacos vermelhos'.
A exclusão não fará mais cascatas e não eliminará as categorias 'botas' e 'casacos'.
comentário comentário:
você ainda está entendendo mal como as exclusões em cascata funcionam. Eles afetam apenas as tabelas nas quais a cascata "ao excluir" é definida. Nesse caso, a cascata é definida na tabela "categories_products". Se você excluir a categoria 'vermelha', os únicos registros que serão excluídos em cascata em categories_products são aqueles em que category_id = red
. Ele não toca em nenhum registro em que 'category_id = blue' e não avança para a tabela "produtos", porque não há chave estrangeira definida nessa tabela.
Aqui está um exemplo mais 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 você exclua a categoria # 2 (azul):
DELETE FROM categories WHERE (id = 2);
o DBMS examinará todas as tabelas que possuem uma chave estrangeira apontando para a tabela 'categorias' e excluirá os registros onde o ID correspondente for 2. Como definimos apenas o relacionamento da chave estrangeira products_categories
, você acaba com essa tabela quando o A exclusão é concluída:
+------------+-------------+
| product_id | category_id |
+------------+-------------+
| 1 | 1 | // red mittens
| 2 | 1 | // red boots
+------------+-------------+
Não há chave estrangeira definida na products
tabela; portanto, a cascata não funcionará lá; portanto, você ainda tem botas e luvas listadas. Não há mais 'botas azuis' e nem 'luvas azuis'.