¿Hay algún momento en el que debamos evitar la eliminación en cascada?

11

En SQL Server 2008, hay una tabla primaria que está vinculada a otras tres tablas secundarias por 1 a muchas relaciones. Por lo tanto, estamos pensando en usar la eliminación en cascada en la tabla primaria, de modo que todos los registros de la tabla secundaria se eliminarán cuando se elimine el registro de la tabla primaria.

  1. Entonces, ¿eliminar en cascada es una opción correcta aquí?
  2. ¿Cuando no se debe usar el detele en cascada?
Ramesh
fuente
3
Nadie puede responder esto sin conocer su caso de uso. La eliminación en cascada siempre tiene el riesgo de que los datos se eliminen fácilmente. Básicamente lo uso muy raramente, en casos donde este es el comportamiento deseado. Estas son tablas muy modificadas en general.
dezso

Respuestas:

17

En general estoy cuidado con las eliminaciones en cascada (y otras acciones automáticas que podrían soltar / daños de datos), ya sea a través de disparadores o ON <something> CASCADE. Tales instalaciones son muy poderosas, pero también potencialmente peligrosas.

  • Entonces, ¿eliminar en cascada es una opción correcta aquí?

Sin duda, haría lo que está buscando: eliminar registros relacionados cuando se elimina un registro principal, sin necesidad de implementar ninguna otra lógica para garantizar que los hijos se eliminen primero, por lo que su código será más conciso. Todas las acciones se envolverán en una transacción implícita, por lo que si algo bloquea al niño, se elimina toda la operación, se mantiene la integridad referencial con poco o ningún esfuerzo de codificación adicional.

Asegúrese de que su uso de eliminaciones en cascada y otras acciones "detrás de escena" estén bien documentadas para que los futuros mantenedores del sistema lo sepan.

  • ¿Cuando no se debe usar el detele en cascada?

¡No debe usarse si eres paranoico como yo! Un punto clave a considerar son los otros desarrolladores que actualmente, o pueden en el futuro, trabajar en su código / base de datos (de ahí el comentario anterior sobre la documentación de cualquier comportamiento "oculto").

En mi experiencia, es bastante común que las personas sin experiencia utilicen DELETEluego re INSERTpara actualizar filas, especialmente cuando lo que realmente quieren es una operación MERGE/ UPSERT(actualizar filas existentes y crear nuevas donde no exista una fila con una clave dada) y el DBMS no admite fusión / inserción (o desconocen su compatibilidad). Sin acciones en cascada, esto es perfectamente seguro (o generará un error cuando amenace la integridad de los datos), pero si alguien hace esto para filas en una tabla principal donde los FK de referencia tienenON DELETE CASCADEestablecer luego, los datos relacionados se eliminarán como resultado de la eliminación inicial y no se reemplazarán, por lo que los datos se pierden (aunque la eliminación y la inserción posterior se envuelven en transacciones explícitas, la cascada ocurre con la operación de eliminación). espere para ver si la transacción reemplaza las filas en la tabla principal en las declaraciones posteriores) y la cascada podría continuar a través de otras relaciones (por ejemplo: eliminar un supervisor superior, su equipo se elimina por cascada, los equipos de sus equipos se eliminan por cascada, todos los registros rastreados para todas esas personas se eliminan en cascada, ...). Sin la conexión en cascada habilitada, solo obtendría un error aquí en lugar de que los datos se pierdan silenciosamente.

David Spillett
fuente
¿Habrá alguna implicación en el rendimiento? ¿Como adquirir un bloqueo y eliminarlo manualmente sería mejor que en cascada?
Ramesh
Asumiría que habría muy poca diferencia, suponiendo que tenga el proceso más manual envuelto en una transacción explícita que debe hacer por cuestiones de coherencia. Los métodos manuales y automáticos (en cascada) se verán afectados por los niveles de bloqueo y aislamiento una vez que se considere la concurrencia, por supuesto.
David Spillett
4

Supongo que la respuesta se reduce a si tiene sentido o no para su situación, depende . Para su situación, ¿tiene sentido que las filas en la tabla 'secundaria' permanezcan si sus filas 'primarias' correspondientes van? ¿Los datos en la tabla secundaria no tendrían sentido sin el padre? Si es así, la eliminación en cascada impondría la integridad referencial. Es posible que desee mantener las filas secundarias como un registro, un archivo de la actividad pasada (aunque potencialmente podría escribir estas filas en otra tabla especialmente para este propósito).

Un ejemplo que uso para ilustrar este punto es la relación médico / paciente. Un médico puede tener muchos pacientes. Un paciente solo puede ser un paciente si tiene un médico. Si el documento desaparece (deja la práctica), entonces algo tiene que sucederle a los pacientes restantes. Una posibilidad es que se purguen. Otra es que un valor predeterminado reemplaza la referencia del documento o podrían eliminarse de la tabla principal y colocarse en otro lugar. Alternativamente, no se produce actividad y los pacientes permanecen como estaban, intactos, como si el documento todavía estuviera presente. Eso depende de lo que quieras hacer.

Por experiencia personal, piense detenidamente sobre el diseño de la base de datos. Esta semana tuve que ejecutar una purga de registros huérfanos en una tabla que no señalaba a ninguna parte y literalmente estaba ocupando espacio.

the_good_pony
fuente
Tengo que eliminar los registros secundarios cuando desaparece el registro primario.
Ramesh
Si los registros deben ir completamente y no tienen sentido mantenerlos, entonces una eliminación en cascada tendría más sentido en su situación
the_good_pony
3

El uso de la eliminación en cascada es una cuestión de preferencia personal, como nombrar tablas con nombres plurales o no (Cliente vs Clientes).

Preferiría nunca usar la eliminación en cascada. Algunos diseños de bases de datos evitan su eliminación. Hay pocas justificaciones para eliminar datos de una base de datos cuando el espacio en disco es tan barato. Algunos diseños de bases de datos establecen un campo adicional "IsDeleted" en lugar de eliminar físicamente los datos.

Si tiene que eliminar datos, el uso de procedimientos almacenados para administrar esto le brinda más transparencia y control. Su aplicación puede ejecutar un procedimiento almacenado que elimina del niño y luego del padre. No sabe cómo cambiarán los requisitos comerciales con el tiempo, por lo que los sp le darán más versatilidad. Ese es mi 2c.

sa555
fuente
Es cierto que le brinda más versatilidad, pero también introduce un comportamiento "oculto", lo que significa que debe tener documentación adicional para esos sps (para que las personas sepan qué acción comercial requiere qué sp). Otra forma podría ser restringir a los usuarios de SQL solo capaz de ejecutar esos sps y no ejecutar otras inserciones / actualizaciones "simples".
DrCopyPaste