¿Cuál es la ventaja de hacer una eliminación lógica / suave de un registro (es decir, establecer una bandera que indique que el registro se elimina) en lugar de eliminar el registro real o físicamente?
¿Es esta una práctica común?
¿Es esto seguro?
¿Cuál es la ventaja de hacer una eliminación lógica / suave de un registro (es decir, establecer una bandera que indique que el registro se elimina) en lugar de eliminar el registro real o físicamente?
¿Es esta una práctica común?
¿Es esto seguro?
Respuestas:
Las ventajas son que mantiene el historial (bueno para la auditoría) y no tiene que preocuparse por eliminar en cascada otras tablas en la base de datos que hacen referencia a la fila que está eliminando. La desventaja es que debe codificar cualquier método de presentación de informes / visualización para tener en cuenta la bandera.
En cuanto a si es una práctica común, diría que sí, pero como con cualquier otra cosa, si lo usa depende de las necesidades de su negocio.
EDITAR: Pensó en otra desventaja: si tiene índices únicos en la tabla, los registros eliminados aún ocuparán el registro "uno", por lo que también debe codificar esa posibilidad (por ejemplo, una tabla de usuario que tiene un índice único en nombre de usuario; Un registro eliminado aún bloquearía el nombre de usuario de los usuarios eliminados para nuevos registros. Para solucionar esto, podría agregar un GUID a la columna de nombre de usuario eliminado, pero es una solución muy peligrosa que no recomendaría. Probablemente en esa circunstancia lo haría sería mejor tener una regla que una vez que se usa un nombre de usuario, nunca se puede reemplazar).
CREATE UNIQUE INDEX ... WHERE DELETED_AT is null
(en PostgreSQL) y luego todas las filas con cualquier fecha de eliminación no están indexadas. (En su lugar, pueden incluirse en un índice no único).
¿Son las eliminaciones lógicas una práctica común? Sí, he visto esto en muchos lugares. ¿Están seguros? Eso realmente depende de si son menos seguros que los datos antes de eliminarlos.
Cuando era Tech Lead, exigí que nuestro equipo mantuviera todos los datos, sabía en ese momento que usaríamos todos esos datos para construir varias aplicaciones de BI, aunque en ese momento no sabíamos cuáles serían los requisitos. ser. Si bien esto fue bueno desde el punto de vista de la auditoría, la resolución de problemas y los informes (este era un sitio de comercio electrónico / herramientas para transacciones B2B, y si alguien usaba una herramienta, queríamos registrarla incluso si su cuenta se apagaba posteriormente), tenía varios inconvenientes.
Las desventajas incluyen (sin incluir otras ya mencionadas):
Al decidir utilizar eliminaciones lógicas, físicas o archivar, me haría estas preguntas:
Activated
tabla y Deactivated
esquema de tabla - Id,Name,etc..
Fila en Activated
- 1001,Smith007,etc...
Cuando está desactivado, entonces podemos borrar todas las columnas excepto ID para smith Activated
y agregarlo Deactivated
.
Puede que sea un poco tarde, pero sugiero a todos que consulten la publicación del blog de Pinal Dave sobre eliminación lógica / suave:
Simplemente no me gusta este tipo de diseño [eliminación suave] en absoluto. Soy un firme creyente de la arquitectura donde solo los datos necesarios deben estar en una sola tabla y los datos inútiles deben moverse a una tabla archivada. En lugar de seguir la columna isDeleted, sugiero el uso de dos tablas diferentes: una con pedidos y otra con pedidos eliminados. En ese caso, tendrás que mantener tanto la mesa, pero en realidad es muy fácil de mantener. Cuando escriba la instrucción UPDATE en la columna isDeleted, escriba INSERT INTO otra tabla y BORRARla de la tabla original. Si la situación es de retroceso, escriba otro INSERT INTO y DELETE en orden inverso. Si le preocupa una transacción fallida, envuelva este código en TRANSACCIÓN.
¿Cuáles son las ventajas de la mesa más pequeña frente a la mesa más grande en las situaciones descritas anteriormente?
- Una mesa más pequeña es fácil de mantener
- Las operaciones de reconstrucción de índices son mucho más rápidas
- Mover los datos del archivo a otro grupo de archivos reducirá la carga del grupo de archivos principal (considerando que todos los grupos de archivos están en un sistema diferente); esto también acelerará la copia de seguridad.
- Las estadísticas se actualizarán con frecuencia debido al tamaño más pequeño y esto requerirá menos recursos.
- El tamaño del índice será menor
- El rendimiento de la mesa mejorará con un tamaño de mesa más pequeño.
Soy desarrollador NoSQL, y en mi último trabajo, trabajé con datos que siempre fueron críticos para alguien, y si se borraron por accidente en el mismo día en que se creó, no pude encontrarlos en la última copia de seguridad. ¡de ayer! En esa situación, la eliminación suave siempre salvó el día.
Hice una eliminación suave usando marcas de tiempo, registrando la fecha en que se eliminó el documento:
IsDeleted = 20150310 //yyyyMMdd
Todos los domingos, un proceso caminaba por la base de datos y verificaba el IsDeleted
campo. Si la diferencia entre la fecha actual y la marca de tiempo era superior a N días, el documento se borraba de forma definitiva. Teniendo en cuenta que el documento todavía está disponible en alguna copia de seguridad, era seguro hacerlo.
EDITAR: Este caso de uso de NoSQL se trata de grandes documentos creados en la base de datos, decenas o cientos de ellos todos los días, pero no miles o millones. Por lo general, eran documentos con el estado, datos y anexos de los procesos de flujo de trabajo. Esa fue la razón por la que existía la posibilidad de que un usuario borrara un documento importante. Este usuario podría ser alguien con privilegios de administrador, o tal vez el propietario del documento, solo por nombrar algunos.
TL; DR Mi caso de uso no fue Big Data. En ese caso, necesitará un enfoque diferente.
Un patrón que he usado es crear una tabla espejo y adjuntar un disparador en la tabla principal, por lo que todas las eliminaciones (y actualizaciones si lo desea) se registran en la tabla espejo.
Esto le permite "reconstruir" registros eliminados / modificados, y aún puede eliminar de forma dura en la tabla principal y mantenerla "limpia"; también permite la creación de una función de "deshacer", y también puede registrar la fecha, la hora y usuario que realizó la acción en la mesa espejo (invaluable en situaciones de caza de brujas).
La otra ventaja es que no hay posibilidad de incluir accidentalmente registros eliminados al consultar el primario a menos que deliberadamente se tome la molestia de incluir registros de la tabla espejo (es posible que desee mostrar registros en vivo y eliminados).
Otra ventaja es que la tabla espejo se puede purgar de forma independiente, ya que no debería tener ninguna referencia de clave externa real, lo que hace que esta sea una operación relativamente simple en comparación con la purga de una tabla principal que usa eliminaciones suaves pero que aún tiene conexiones referenciales a otras tablas.
¿Qué otras ventajas? - genial si tiene un grupo de codificadores trabajando en el proyecto, haciendo lecturas en la base de datos con habilidad mixta y atención a los niveles de detalle, no tiene que quedarse despierto por la noche esperando que uno de ellos no se olvide de no incluir borrado registros (jajaja, No incluir registros eliminados = Verdadero), lo que da como resultado cosas como exagerar, decir la posición de efectivo disponible del cliente con la que luego van a comprar algunas acciones (es decir, como en un sistema de negociación), cuando trabaja con sistemas de negociación, Descubrirá muy rápidamente el valor de las soluciones robustas, aunque pueden tener un poco más de "gastos generales" iniciales.
Excepciones:
- como guía, use eliminaciones suaves para datos de "referencia" como usuario, categoría, etc., y eliminaciones permanentes en una tabla espejo para datos de tipo "hechos", es decir, historial de transacciones.
Normalmente uso eliminaciones lógicas: encuentro que funcionan bien cuando también archiva de manera intermitente los datos 'eliminados' en una tabla archivada (que se puede buscar si es necesario), por lo que no hay posibilidad de afectar el rendimiento de la aplicación.
Funciona bien porque todavía tiene los datos si alguna vez lo auditan. Si lo borra físicamente, ¡ desaparecerá !
Soy un gran admirador de la eliminación lógica, especialmente para una aplicación de línea de negocio, o en el contexto de cuentas de usuario. Mis razones son simples: muchas veces no quiero que un usuario pueda usar más el sistema (por lo que la cuenta se marca como eliminada), pero si elimináramos al usuario, perderíamos todo su trabajo y demás.
Otro escenario común es que los usuarios pueden volver a crearse un tiempo después de haber sido eliminados. Es una experiencia mucho más agradable para el usuario tener todos sus datos presentes como estaban antes de ser eliminados, en lugar de tener que volver a crearlos.
Por lo general, pienso en eliminar usuarios más como "suspenderlos" indefinidamente. Nunca se sabe cuándo necesitarán legítimamente regresar.
Casi siempre elimino suavemente y he aquí por qué:
isdeleted
todas partes no es un problema, debe verificar de userid
todos modos (si la base de datos contiene datos de varios usuarios). Puede hacer cumplir la verificación por código, colocando esas dos verificaciones en una función separada (o usar vistas)Re: "¿Es esto seguro?" - eso depende de lo que quieras decir.
Si quiere decir que al hacer una eliminación física, evitará que alguien encuentre los datos eliminados , entonces sí, eso es más o menos cierto; está más seguro al eliminar físicamente los datos confidenciales que deben borrarse, porque eso significa que se eliminan permanentemente de la base de datos. (Sin embargo, tenga en cuenta que puede haber otras copias de los datos en cuestión, como en una copia de seguridad o en el registro de transacciones, o una versión grabada en tránsito, por ejemplo, un rastreador de paquetes, solo porque elimine de su base de datos no garantizar que no se guardó en otro lugar).
Si quiere decir que al hacer una eliminación lógica, sus datos están más seguros porque nunca perderá ningún dato , eso también es cierto. Esto es bueno para escenarios de auditoría; Tiendo a diseñar de esta manera porque admite el hecho básico de que una vez que se generan los datos, nunca desaparecerán realmente (especialmente si alguna vez tuvieron la capacidad de ser, digamos, almacenados en caché por un motor de búsqueda de Internet). Por supuesto, un escenario de auditoría real requiere que no solo las eliminaciones sean lógicas, sino que también se registren las actualizaciones, junto con la hora del cambio y el actor que realizó el cambio.
Si quiere decir que los datos no caerán en manos de nadie que no debería verlos, entonces eso depende totalmente de su aplicación y su estructura de seguridad. En ese sentido, la eliminación lógica no es ni más ni menos segura que cualquier otra cosa en su base de datos.
Estoy totalmente en desacuerdo con la eliminación lógica porque estás expuesto a muchos errores.
En primer lugar las consultas, cada consulta debe cuidar el campo IsDeleted y la posibilidad de error aumenta con consultas complejas.
Segundo el rendimiento: imagina una tabla con 100000 recs con solo 3 activos, ahora multiplica este número por las tablas de tu base de datos; Otro problema de rendimiento es un posible conflicto con registros nuevos con registros antiguos (registros eliminados).
La única ventaja que veo es el historial de registros, pero existen otros métodos para lograr este resultado, por ejemplo, puede crear una tabla de registro donde puede guardar información: TableName,OldValues,NewValues,Date,User,[..]
dónde *Values
puede estar varchar
y escribir los detalles en este formulario fieldname : value
; [..] o almacenar la información como xml
.
Todo esto se puede lograr mediante código o Triggers, pero solo eres UNA mesa con todo tu historial. Otra opción es ver si el motor de base de datos especificado es soporte nativo para el seguimiento de cambios, por ejemplo, en la base de datos de SQL Server hay SQL Track Data Change.
Solía hacer una eliminación temporal, solo para mantener registros antiguos. Me di cuenta de que los usuarios no se molestan en ver registros antiguos con tanta frecuencia como pensaba. Si los usuarios quieren ver registros antiguos, pueden verlos desde el archivo o la tabla de auditoría, ¿verdad? Entonces, ¿cuál es la ventaja de la eliminación suave? Solo conduce a una declaración de consulta más compleja, etc.
Las siguientes son las cosas que implementé, antes de decidir no eliminar más:
implementar auditoría, para registrar todas las actividades (agregar, editar, eliminar). Asegúrese de que no haya ninguna clave externa vinculada a la auditoría y asegúrese de que esta tabla esté protegida y que nadie pueda eliminarla excepto los administradores.
identificar qué tablas se consideran "tablas transaccionales", cuáles es muy probable que se mantengan durante mucho tiempo, y es muy probable que el usuario desee ver los registros o informes anteriores. Por ejemplo; transacción de compra. Esta tabla no solo debe mantener la identificación de la tabla maestra (como dept-id), sino también la información adicional como el nombre como referencia (como dept-name) o cualquier otro campo necesario para la generación de informes.
Implementar el registro "activo / inactivo" o "habilitar / deshabilitar" u "ocultar / mostrar" de la tabla maestra. Entonces, en lugar de eliminar el registro, el usuario puede deshabilitar / inactivar el registro maestro. Es mucho más seguro de esta manera.
Solo mi opinión de dos centavos.
Las eliminaciones lógicas son difíciles para la integridad referencial.
Es lo correcto cuando hay un aspecto temporal de los datos de la tabla (son válidos FROM_DATE - TO_DATE).
De lo contrario, mueva los datos a una tabla de auditoría y elimine el registro.
En el lado positivo:
Es la forma más fácil de revertir (si es posible).
Es fácil ver cuál era el estado en un momento específico.
Es bastante estándar en los casos en los que le gustaría mantener un historial de algo (por ejemplo, cuentas de usuario como menciona @Jon Dewees). Y ciertamente es una gran idea si existe una gran posibilidad de que los usuarios soliciten que se eliminen.
Si le preocupa que la lógica de filtrar los registros eliminados de sus consultas se vuelva desordenada y solo complique sus consultas, puede crear vistas que hagan el filtrado por usted y usar consultas en contra de eso. Evitará la filtración de estos registros en soluciones de informes y demás.
Hay requisitos más allá del diseño del sistema que necesitan respuesta. ¿Cuál es el requisito legal o estatutario en la retención de registros? Dependiendo de con qué se relacionen las filas, puede haber un requisito legal de que los datos se conserven durante un cierto período de tiempo después de que se "suspendan".
Por otro lado, el requisito puede ser que una vez que se 'borre' el registro, se borre verdadera e irrevocablemente. Antes de tomar una decisión, hable con sus partes interesadas.
Las aplicaciones móviles que dependen de la sincronización pueden imponer el uso de eliminación lógica en lugar de física: un servidor debe poder indicarle al cliente que un registro se ha (marcado como) eliminado, y esto podría no ser posible si los registros se eliminaron físicamente.
No permiten que la base de datos funcione como debería, haciendo inútiles cosas como la funcionalidad en cascada.
Para cosas simples como inserciones, en el caso de volver a insertar, el código detrás se duplica.
No puede simplemente insertar, sino que debe verificar la existencia e insertar si no existe antes o actualizar la marca de eliminación si lo hace, al mismo tiempo que actualiza todas las demás columnas a los nuevos valores. Esto se ve como una actualización del registro de transacciones de la base de datos y no como una nueva inserción que causa registros de auditoría inexactos.
Causan problemas de rendimiento porque las tablas se llenan de datos redundantes. Hace estragos en la indexación, especialmente con la singularidad.
No soy un gran fanático de las eliminaciones lógicas.
Para responder al comentario de Tohid, nos enfrentamos al mismo problema en el que queríamos conservar el historial de registros y tampoco estábamos seguros de si queríamos is_deleted
columna o no.
Estoy hablando de nuestra implementación de Python y un caso de uso similar al que llegamos.
Encontramos https://github.com/kvesteri/sqlalchemy-continuum, que es una forma fácil de obtener una tabla de versiones para su tabla correspondiente. Líneas mínimas de código y captura el historial para agregar, eliminar y actualizar.
Esto sirve para algo más que una is_deleted
columna. Siempre puede hacer backref en la tabla de versiones para verificar qué sucedió con esta entrada. Si la entrada se eliminó, actualizó o agregó.
De esta manera no necesitábamos tener ninguna is_deleted
columna y nuestra función de eliminación era bastante trivial. De esta manera tampoco necesitamos recordar marcar is_deleted=False
en ninguna de nuestras api.
Soft Delete es una práctica de programación que se sigue en la mayoría de las aplicaciones cuando los datos son más relevantes. Considere un caso de aplicación financiera donde una eliminación por error del usuario final puede ser fatal. Ese es el caso cuando la eliminación suave se vuelve relevante. En el borrado suave, el usuario no borra realmente los datos del registro, sino que se marca como IsDeleted como verdadero (por convención normal).
En EF 6.xo EF 7 en adelante, Softdelete se agrega como un atributo, pero tenemos que crear un atributo personalizado por el momento.
Recomiendo encarecidamente SoftDelete en un diseño de base de datos y es una buena convención para la práctica de programación.
La mayoría de las veces, se usa la eliminación suave porque no desea exponer algunos datos, pero debe conservarlos por razones históricas (un producto podría descontinuarse, por lo que no desea ninguna transacción nueva con él, pero aún necesita trabajar con el historial de transacciones de venta). Por cierto, algunos están copiando el valor de la información del producto en los datos de la transacción de venta en lugar de hacer una referencia al producto para manejar esto.
De hecho, parece más una nueva redacción de una característica visible / oculta o activa / inactiva. Porque ese es el significado de "eliminar" en el mundo empresarial. Me gustaría decir que Terminator puede eliminar personas, pero el jefe simplemente las despide.
Esta práctica es un patrón bastante común y es utilizada por muchas aplicaciones por muchas razones. Como no es la única manera de lograr esto, tendrás miles de personas diciendo que eso es genial o una mierda y ambos tienen muy buenos argumentos.
Desde el punto de vista de la seguridad, SoftDelete no reemplazará el trabajo de auditoría y tampoco reemplazará el trabajo de respaldo. Si tiene miedo de "insertar / eliminar entre dos casos de copia de seguridad", debe leer sobre los modelos de recuperación completa o masiva. Admito que SoftDelete podría hacer que el proceso de recuperación sea más trivial.
Depende de usted conocer su requerimiento.
Para dar una alternativa, tenemos usuarios que utilizan dispositivos remotos que se actualizan a través de MobiLink. Si eliminamos registros en la base de datos del servidor, esos registros nunca se marcan como eliminados en las bases de datos del cliente.
Entonces hacemos ambas cosas. Trabajamos con nuestros clientes para determinar cuánto tiempo desean poder recuperar datos. Por ejemplo, generalmente los clientes y los productos están activos hasta que nuestro cliente dice que deben eliminarse, pero el historial de ventas solo se conserva durante 13 meses y luego se elimina automáticamente. Es posible que el cliente desee mantener los clientes y productos eliminados durante dos meses, pero conservar el historial durante seis meses.
Así que ejecutamos un script durante la noche que marca las cosas borradas lógicamente de acuerdo con estos parámetros y luego, dos o seis meses después, todo lo marcado como borrado lógicamente hoy se borrará de forma definitiva.
Nos preocupamos menos por la seguridad de los datos que por tener enormes bases de datos en un dispositivo cliente con memoria limitada, como un teléfono inteligente. Un cliente que pide 200 productos dos veces por semana durante cuatro años tendrá más de 81.000 líneas de historial, de las cuales al 75% no le importa si las ve.
Todo depende del caso de uso del sistema y sus datos.
Por ejemplo, si está hablando de un sistema regulado por el gobierno (por ejemplo, un sistema en una compañía farmacéutica que se considera parte del sistema de calidad y debe seguir las pautas de la FDA para registros electrónicos), entonces es mejor que no haga borrados. Un auditor de la FDA puede venir y solicitar todos los registros del sistema relacionados con el número de producto ABC-123, y será mejor que todos los datos estén disponibles. Si el propietario de su proceso de negocio dice que el sistema no debería permitir que nadie use el número de producto ABC-123 en nuevos registros en el futuro, use el método de eliminación temporal para hacerlo "inactivo" dentro del sistema, mientras conserva los datos históricos.
Sin embargo, tal vez su sistema y sus datos tengan un caso de uso como "rastrear el clima en el Polo Norte". Tal vez tome lecturas de temperatura una vez cada hora y, al final del día, agregue un promedio diario. Tal vez los datos por hora ya no se utilicen después de la agregación, y eliminaría las lecturas por hora después de crear el agregado. (Este es un ejemplo trivial inventado).
La cuestión es que todo depende del caso de uso del sistema y sus datos, y no de una decisión que deba tomarse puramente desde un punto de vista tecnológico.
¡Bien! Como decían todos, depende de la situación.
Si tiene un índice en una columna como UserName o EmailID, y nunca espera que se vuelva a utilizar el mismo UserName o EmailID; puede ir con una eliminación suave.
Dicho esto, siempre verifique si su operación SELECT usa la clave principal. Si su declaración SELECT usa una clave principal, agregar una bandera con la cláusula WHERE no haría mucha diferencia. Tomemos un ejemplo (Pseudo):
Usuarios de la tabla (UserID [clave principal], EmailID, IsDeleted)
SELECT * FROM Users where UserID = 123456 and IsDeleted = 0
Esta consulta no hará ninguna diferencia en términos de rendimiento ya que la columna UserID tiene una clave principal. Inicialmente, escaneará la tabla basándose en PK y luego ejecutará la siguiente condición.
Casos en los que las eliminaciones suaves no pueden funcionar en absoluto:
El registro en la mayoría de los sitios web toma EmailID como su identificación única. Sabemos muy bien que una vez que se utiliza un ID de correo electrónico en un sitio web como Facebook, G +, nadie más puede utilizarlo.
Llega un día en que el usuario quiere eliminar su perfil del sitio web. Ahora, si realiza una eliminación lógica, ese usuario no podrá registrarse nunca más. Además, registrarse nuevamente con el mismo ID de correo electrónico no significaría restaurar todo el historial. Todo el mundo sabe, borrar significa borrar. En tales escenarios, tenemos que hacer una eliminación física. Pero para mantener el historial completo de la cuenta, siempre debemos archivar dichos registros en tablas de archivo o tablas eliminadas.
Sí, en situaciones en las que tenemos muchas tablas extranjeras, el manejo es bastante engorroso.
También tenga en cuenta que las eliminaciones lógicas / suaves aumentarán el tamaño de su tabla, por lo que el tamaño del índice.
Ya he respondido en otro post . Sin embargo, creo que mi respuesta se ajusta más a la pregunta aquí.
Mi solución práctica para soft-supresión se archiva mediante la creación de una nueva tabla con las columnas siguientes:
original_id
,table_name
,payload
, (y opcional clave primaria `id).Donde
original_id
está la identificación original del registro eliminado,table_name
es el nombre de la tabla del registro eliminado ("user"
en su caso),payload
es una cadena JSON-stringificada de todas las columnas del registro eliminado.También sugiero hacer un índice en la columna
original_id
para la última recuperación de datos.De esta forma de archivar datos. Tendrás estas ventajas
- Mantenga un registro de todos los datos en el historial
- Tener un solo lugar para archivar registros de cualquier tabla, independientemente de la estructura de la tabla del registro eliminado
- No se preocupe por el índice único en la tabla original
- No se preocupe por verificar el índice extranjero en la tabla original
- No más
WHERE
cláusulas en cada consulta para verificar la eliminaciónYa hay una discusión aquí que explica por qué la eliminación suave no es una buena idea en la práctica. Soft-delete introduce algunos problemas potenciales en el futuro, como contar registros, ...
Las ventajas son la conservación / perpetuación de datos. Una desventaja sería una disminución en el rendimiento al consultar o recuperar datos de tablas con una cantidad significativa de eliminaciones suaves. En nuestro caso utilizamos una combinación de ambos: como otros han mencionado en respuestas anteriores, soft-delete
users/clients/customers
por ejemplo, y hard-delete
en items/products/merchandise
tablas donde hay registros duplicados que no necesitan apicultura.
Depende del caso, considere lo siguiente:
Por lo general, no es necesario "eliminar temporalmente" un registro. Manténgalo simple y rápido. por ejemplo, eliminar un producto que ya no está disponible, por lo que no tiene que verificar que el producto no se haya eliminado temporalmente en toda su aplicación (recuento, lista de productos, productos recomendados, etc.).
Sin embargo, podría considerar la "eliminación suave" en un modelo de almacén de datos. Por ejemplo, está viendo un recibo antiguo en un producto eliminado. *