¿Cuál es la mejor manera de vaciar una tabla MySQL autorreferencial?
-
03-07-2019 - |
Pregunta
Tengo una tabla MySQL autorreferencial con un parent_id recursivo:
CREATE TABLE `recursive` (
`id` int(11) NOT NULL auto_increment,
`parent_id` int(11) default NULL,
`name` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
KEY `data_categorysource_parent_id` (`parent_id`),
CONSTRAINT `parent_id_refs_id_627b4293`
FOREIGN KEY (`parent_id`) REFERENCES `data_categorysource` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Durante la prueba, quiero vaciarlo pero TRUNCATE falla:
TRUNCATE `recursive`
/* SQL Error: Cannot delete or update a parent row: a foreign key
constraint fails...
Actualmente tengo que eliminar manualmente todos los registros, comenzando en la parte inferior del árbol hacia arriba. Esto se vuelve oneroso incluso con árboles pequeños.
¿Hay alguna manera fácil de evitar esto? No puedo DROP
la tabla y volver a crearla fácilmente como otras tablas hacen referencia a ella (ya las he truncado, por lo que no debería haber problemas de integridad de datos allí).
Solución
¿Por qué no?
UPDATE 'recursive' SET 'parent_id' = NULL WHERE 'parent_id' IS NOT NULL;
DELETE FROM 'recursive';
?
Otros consejos
Si solo quiere vaciarlo todo con fines de prueba, use:
SET FOREIGN_KEY_CHECKS = 0;
// Execute Query
SET FOREIGN_KEY_CHECKS = 1;
Esto omite totalmente cualquier comprobación de clave externa.
Bueno, podría agregar un ON DELETE CASCADE
a la definición de FOREIGN KEY
... al menos temporalmente. Eso le permitiría truncar la tabla eliminando primero las filas a las que se hace referencia.
Hay otros ON DELETE
tipos también; el valor predeterminado es ON DELETE NO ACTION
.
O simplemente elimine la restricción de clave externa (recursiva), luego trunque la tabla y luego vuelva a agregar la restricción.
Seleccione repetidamente las filas que no aparecen como padres y elimínelas, hasta que la tabla esté vacía. (Suponiendo que no haya ciclos ...)
eliminar de la tabla_1 donde date (table_1_TIME) < (seleccione T.t_Date de (seleccione max (date (table_1_TIME)) como t_Date de table_1) como T)