Solo trato de obtener algunas ideas sobre lo que la gente hace para este escenario. Tenemos una base de datos del sistema (SQL Server 2008 R2) que tiene tablas y cada tabla tiene un campo que podemos llamar "Eliminado". Básicamente es un campo de bits si es un 1, el registro se elimina, si es un 0, no se elimina. El campo no es anulable y su valor predeterminado es, por supuesto, 0.
No podemos permitir eliminaciones reales en la base de datos, por lo que para evitar esto, establecemos un campo de bits (Eliminado) en verdadero. En nuestra aplicación terminamos con consultas que se ven así:
SELECT blah FROM MyTable WHERE .. AND Deleted=0
Básicamente, filtramos los registros para que solo obtengamos filas no eliminadas. Nuestro problema son los registros relacionados que deben conectarse en cascada. ¿Qué prefiere la gente? ¿Deberíamos hacer esto en el código del lado del servidor para que cuando elimine un registro se elimine (establece el campo de bits eliminado en verdadero) para todos los registros relacionados? ¿O debería ser este un disparador que tiene que verificar este campo y establece el campo de bits para todos los registros relacionados en 1?
¿O estamos completamente en el camino equivocado?
Respuestas:
No hay una buena solución aquí. Las bases de datos ofrecen una eliminación en cascada especial y eficiente a través de claves externas, pero si, como usted dice, la eliminación real no es una opción, entonces no puede aprovechar esa conexión en cascada nativa.
Dependiendo de si las eliminaciones son una ocurrencia común o rara, será más eficiente emular la cascada inmediatamente (a través de consultas o desencadenantes adicionales) cuando se pseudo-elimina algo, o simplemente para buscar todo desde el DB y filtrar la eliminación Bandera en lógica de negocios.
Personalmente, siempre he usado una tercera opción: solo se puede acceder a todos los registros subsidiarios desde el registro maestro, lo que nunca sucede si ese se elimina de forma parcial, ¡por lo que no necesita hacer nada! Obviamente, esto solo funciona si su modelo de datos es un árbol estricto (los comentarios solo se recuperan al ver el producto al que se aplican, los privilegios del usuario solo se recuperan al administrar el usuario al que pertenecen, etc.) en lugar de una web (donde puede consultar todos los comentarios o todos los registros de privilegios indiferentemente), pero creo que esto puede funcionar para sorprendentemente muchos escenarios.
fuente
He hecho esto antes con tablas de auditoría en las que cada cambio en una base de datos se escribe en una tabla espejo de auditoría (Insertar / Actualizar / Eliminar) y los elementos reales reales se eliminan en cascada.
Las tablas espejo son idénticas a la tabla real con la adición de 3 columnas, "ChangeType", "User", "Date".
Esto tiene la doble ventaja de poder eliminar datos correctamente, pero también permite recrear el estado de la base de datos en cualquier momento y documentar el historial completo de cualquier elemento.
Agregaré eso para las eliminaciones en cascada, generalmente prefiero las eliminaciones en cascada en el cliente: el servidor no debería intentar ser demasiado inteligente al respecto, si un usuario elimina una empresa y eso tiene problemas asociados, la acción de eliminar la empresa también debería eliminar cualquier registro correspondiente.
Esto era para un sistema de gestión financiera para un banco de inversión importante, por lo que la auditabilidad era una característica crítica.
fuente
Hazlo explícitamente en la declaración delete / undelete. También es probable que haya varios escenarios en los que no desee poner en cascada la eliminación.
Por ejemplo; considere a una persona con varias direcciones.
Eliminando a la persona, simplemente configure Eliminar bandera en persona. No es necesario poner en cascada la eliminación de direcciones, porque cuando restauramos, queremos que esas direcciones vuelvan.
Digamos que la persona se mudó, entonces nos gustaría actualizar el indicador de eliminación solo en la dirección anterior, dejando solo las otras direcciones y la persona. Por lo tanto, la conexión en cascada no siempre es necesaria y dependerá del escenario.
Por lo tanto, creo que debe ser explícito dependiendo de cómo esté configurado su modelo y de lo que esté eliminando.
fuente