Pregunta

Estamos trabajando en un proyecto en este momento y tenemos que implementar la eliminación temporal para la mayoría de los usuarios (roles de usuario).Decidimos agregar un campo "is_deleted='0'" en cada tabla de la base de datos y configurarlo en '1' si roles de usuario particulares presionan un botón de eliminar en un registro específico.

Para el mantenimiento futuro ahora, cada consulta SELECT deberá asegurarse de que no incluya registros donde is_deleted='1'.

¿Existe una solución mejor para implementar la eliminación temporal?

Actualizar:También debo señalar que tenemos una base de datos de auditoría que rastrea los cambios (campo, valor antiguo, valor nuevo, hora, usuario, ip) en todas las tablas/campos dentro de la base de datos de la aplicación.

¿Fue útil?

Solución

Puede realizar todas sus consultas en una vista que contenga el WHERE IS_DELETED='0' cláusula.

Otros consejos

Me inclinaría por el "modo Rails" con un deleted_at columna que contiene el fecha y hora en que tuvo lugar la eliminación.Luego obtienes algunos metadatos gratuitos sobre la eliminación.Para tu SELECT solo obtén filas WHERE deleted_at IS NULL

Teniendo is_deleted La columna es un enfoque razonablemente bueno.Si está en Oracle, para aumentar aún más el rendimiento, recomendaría particionar la tabla creando una partición de lista en is_deleted columna.Luego, las filas eliminadas y no eliminadas estarán físicamente en particiones diferentes, aunque para usted será transparente.

Como resultado, si escribe una consulta como

SELECT * FROM table_name WHERE is_deleted = 1

luego Oracle realizará la 'poda de partición' y solo buscará en la partición apropiada.Internamente una partición es una tabla diferente, pero es transparente para usted como usuario:Podrás seleccionar en toda la tabla sin importar si está particionada o no.Pero Oracle podrá consultar SÓLO la partición que necesita.Por ejemplo, supongamos que tiene 1000 filas con is_deleted = 0 y 100000 filas con is_deleted = 1, y divides la tabla en is_deleted.Ahora si incluyes la condición

WHERE ... AND IS_DELETED=0

entonces Oracle SÓLO escaneará la partición con 1000 filas.Si la tabla no estuviera particionada, tendría que escanear 101000 filas (ambas particiones).

Si la tabla es grande y el rendimiento es un problema, siempre puede mover los registros "eliminados" a otra tabla, que tiene información adicional como la hora de eliminación, quién eliminó el registro, etc.

de esa manera no tendrás que agregar otra columna a tu tabla principal

Lamentablemente, la mejor respuesta depende de lo que esté tratando de lograr con sus eliminaciones temporales y de la base de datos en la que esté implementando esto.

En SQL Server, la mejor solución sería utilizar una columna eliminado_en/eliminado_at con un tipo de SMALLDATETIME o DATETIME (dependiendo de la granularidad necesaria) y hacer que esa columna sea anulable.En SQL Server, los datos del encabezado de fila contienen una máscara de bits NULL para cada una de las columnas de la tabla, por lo que es marginalmente más rápido realizar IS NULL o IS NOT NULL que verificar el valor almacenado en una columna.

Si tiene un gran volumen de datos, querrá considerar la posibilidad de particionar sus datos, ya sea a través de la base de datos misma o mediante dos tablas separadas (p. ej.Products y ProductHistory) o mediante una vista indexada.

Normalmente evito campos de bandera como is_deleted, is_archive, etc. porque solo tienen un significado.Un campo con capacidad anulable eliminado_en, archivado_en proporciona un nivel adicional de significado para usted y para quien herede su aplicación.Y evito los campos de máscara de bits como la plaga, ya que requieren una comprensión de cómo se construyó la máscara de bits para poder captar cualquier significado.

Eso depende de la información que necesite y de los flujos de trabajo que desee admitir.

¿Quieres poder:

  • ¿Sabes qué información había allí (antes de que fuera eliminada)?
  • ¿Sabes cuando fue eliminado?
  • ¿Sabes quién lo eliminó?
  • ¿Sabes en qué capacidad actuaban cuando lo eliminaron?
  • ¿Podré recuperar el registro?
  • ¿Podrás saber cuándo se recuperó?
  • etc.

Si el registro se eliminó y se recuperó cuatro veces, ¿es suficiente que sepa que actualmente se encuentra en un estado no eliminado o desea poder saber qué sucedió mientras tanto (incluidas las ediciones entre registros sucesivos)? eliminaciones!)?

Tenga cuidado con los registros eliminados temporalmente que causan violaciones de las restricciones de unicidad.Si su base de datos tiene columnas con restricciones únicas, tenga cuidado de que los registros eliminados temporalmente no le impidan volver a crear el registro.

Piensa en el ciclo:

  1. crear usuario (iniciar sesión=JOE)
  2. eliminación temporal (establece la columna eliminada como no nula).
  3. (re) crear usuario (iniciar sesión=JOE).ERROR.LOGIN=JOE ya está ocupado

La segunda creación da como resultado una violación de la restricción porque login=JOE ya está en la fila eliminada temporalmente.

Algunas técnicas:1.Mueva el registro eliminado a una nueva tabla.2.Establezca su restricción de unicidad en la columna de inicio de sesión y de marca de tiempo eliminada_en

Mi propia opinión es +1 por pasar a una nueva mesa.Se necesita mucha disciplina para mantener el * y Delete_at = null * en todas sus consultas (para todos sus desarrolladores)

Definitivamente tendrá un mejor rendimiento si mueve los datos eliminados a otra tabla como dijo Jim, además de tener un registro de cuándo se eliminaron, por qué y quién.

Añadiendo where deleted=0 a todas sus consultas las ralentizará significativamente y obstaculizará el uso de cualquiera de los índices que pueda tener en la mesa.Evite tener "banderas" en sus tablas siempre que sea posible.

Algo que uso en los proyectos es una columna de statusind Tinyint, no NULL predeterminada 0, utilizando statusind, ya que una masma de bitsk me permite realizar la gestión de datos (eliminar, archivar, replicar, restaurar, etc.).Al usar esto en las vistas, puedo realizar la distribución de datos, la publicación, etc. para las aplicaciones consumidoras.Si el rendimiento es una preocupación con respecto a las vistas, use pequeñas tablas de hechos para respaldar esta información, descartando el hecho, descartando la relación y permitiendo eliminaciones llamadas.

Se escala bien y se centra en los datos, lo que mantiene la huella de datos bastante pequeña: clave para más de 350 GB de bases de datos con preocupaciones en tiempo real.El uso de alternativas, tablas y activadores tiene algunos gastos generales que, según la necesidad, pueden funcionar o no para usted.

Las auditorías relacionadas con SOX pueden requerir más de un campo para ayudar en su caso, pero esto puede ayudar.Disfrutar

No mencionas qué producto, pero SQL Server 2008 y postgresql (y otros, estoy seguro) te permiten crear índices filtrados, por lo que podrías crear un índice de cobertura donde is_deleted=0, mitigando algunos de los aspectos negativos de este enfoque en particular. .

Prefiero mantener una columna de estado, para poder usarla para varias configuraciones diferentes, es decir.publicado, privado, eliminado, necesita aprobación...

use una vista, función o procedimiento que verifique is_deleted=0, es decirNo seleccione directamente en la tabla en caso de que la tabla necesite cambiar más adelante por otras razones.

e indexar la columna is_deleted para tablas más grandes

Dado que ya tiene un registro de auditoría, el seguimiento de la fecha de eliminación es redundante.

Cree otro esquema y otórguelo todo en su esquema de datos.Implemente VPD en su nuevo esquema para que todas y cada una de las consultas tengan agregado el predicado que permite la selección de la fila no eliminada.http://download.oracle.com/docs/cd/E11882_01/server.112/e16508/cmntopc.htm#CNCPT62345

@AdditionalCriteria("this.status <> 'eliminado'")

pon esto encima de tu @entidad

http://wiki.eclipse.org/EclipseLink/Examples/JPA/SoftDelete

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top