Quiero usar claves externas para mantener la integridad y evitar huérfanos (ya uso innoDB).
¿Cómo hago una declaración SQL que BORRAR EN CASCADA?
Si elimino una categoría, ¿cómo me aseguro de que no elimine productos que también están relacionados con otras categorías?
La tabla dinámica "categories_products" crea una relación de muchos a muchos entre las otras dos tablas.
categories
- id (INT)
- name (VARCHAR 255)
products
- id
- name
- price
categories_products
- categories_id
- products_id
mysql
foreign-keys
innodb
Cudos
fuente
fuente
Respuestas:
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:
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
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:
Digamos que eliminas la categoría # 2 (azul):
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: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'.fuente
CASCADE
operar. De lo contrario, se utilizará el valor predeterminado de MySQL, MyISAM, y MyISAM no admiteCASCADE
operaciones. Para hacer esto, solo agregueENGINE InnoDB
antes del último;
.La respuesta a esta pregunta me confundió, así que creé un caso de prueba en MySQL, espero que esto ayude
fuente
Creo (no estoy seguro) que las restricciones de clave externa no harán exactamente lo que quieres dado el diseño de tu tabla. Quizás lo mejor que puede hacer es definir un procedimiento almacenado que eliminará una categoría de la manera que desee, y luego llamar a ese procedimiento cada vez que desee eliminar una categoría.
También debe agregar las siguientes restricciones de clave externa a la tabla de enlaces:
La cláusula CONSTRAINT, por supuesto, también puede aparecer en la instrucción CREATE TABLE.
Una vez creados estos objetos de esquema, puede eliminar una categoría y obtener el comportamiento que desea emitiendo
CALL DeleteCategory(category_ID)
(donde category_ID es la categoría que se eliminará), y se comportará como lo desee. Pero no emita unaDELETE FROM
consulta normal , a menos que desee un comportamiento más estándar (es decir, elimine solo de la tabla de enlace y deje laproducts
tabla sola).fuente
KEY pkey (product_id),
la terceraCREATE TABLE
consulta en la respuesta aceptada?