2008-08-23 9 views
24

¿Cuáles son algunas estrategias con las que la gente ha tenido éxito para mantener un historial de cambios para los datos en una base de datos bastante compleja? Una de las aplicaciones que uso y desarrollo con frecuencia podría beneficiarse realmente de una forma más completa de seguimiento de cómo los registros han cambiado con el tiempo. Por ejemplo, en este momento los registros pueden tener una cantidad de campos de fecha y hora y campos de usuario modificados, pero actualmente no tenemos un esquema para registrar múltiples cambios, por ejemplo, si una operación se revierte. En un mundo ideal, sería posible reconstruir el registro como lo fue después de cada parada, etc.¿Estrategia efectiva para dejar una pista de auditoría/historial de cambios para aplicaciones DB?

algo de información sobre el DB:

  • Necesita tener la capacidad de crecer por miles de registros por
  • semana
  • 50-60 tablas
  • principal Revisioned tablas pueden tener varios millones de registros de cada
  • cantidad razonable de claves externas e índices establecer
  • Usando PostgreSQL 8.x
+0

Considere el uso de una [base de datos temporal] (http://en.wikipedia.org/wiki/Temporal_database "entrada de Wikipedia"). –

Respuesta

9

En el pasado he usado desencadenantes para construir db update/insert/delete logging.

Puede insertar un registro cada vez que una de las acciones anteriores se realiza en una tabla específica en una tabla de registro que realiza un seguimiento de la acción, qué usuario de db lo hizo, marca de tiempo, tabla en la que se realizó y valor anterior .

Probablemente haya una mejor respuesta, ya que esto requeriría que guarde en caché el valor antes de que se realice la eliminación o actualización real, creo. Pero podrías usar esto para hacer retrocesos.

+8

El problema con una solución de nivel de base de datos es que no existe un contexto comercial para la acción, es decir, no se sabe qué usuario lo hizo o qué estaba haciendo. La mayoría de las aplicaciones web se conectan a su base de datos con un solo nombre de usuario, por lo que el nombre de usuario web registrado no es el nombre de usuario visto por el desencadenador. –

+8

Andrew, cualquier solución que no sea a nivel de base de datos no es una pista de auditoría, ya que no capturará registros no agregados en la GUI. La nuestra atrapa usuarios específicos porque todas nuestras tablas tienen una columna last_updated y las inserciones, actualizaciones, etc. todas envían el person_id de la persona que realiza la actualización, no el nombre de usuario web. – HLGEM

22

Una estrategia que podría utilizar es MVCC, Control de Concurrencia de Múltiples Valores. En este esquema, nunca hace actualizaciones en ninguna de sus tablas, simplemente inserta, manteniendo números de versión para cada registro. Esto tiene la ventaja de proporcionar una instantánea exacta desde cualquier punto en el tiempo, y también evita completamente los problemas de bloqueo de actualización que afectan a muchas bases de datos.

Pero hace una gran base de datos y selecciona todas requieren una cláusula adicional para seleccionar la versión actual de un registro.

+2

¿Cómo sabes cuál es la versión actual? Con una orden top 1 por cláusula desc? @Eric Z Beard –

+0

@ismailyavuz hay esta opción, supongo: agregue una columna booleana extra, 'is_current'. Y mantenerlo constante mediante desencadenadores, y posiblemente una restricción de exclusividad para '(natural_id, is_current = 1)'. –

+0

@ismailyavuz también vea esto: https://stackoverflow.com/a/1051494/1475331 (use los campos 'from' y' to'). La cláusula "where" que selecciona la versión actual de la fila sería "WHERE" a "IS NULL". –

10

Si está utilizando Hibernate, eche un vistazo a JBoss Envers. Desde la página principal del proyecto:

El proyecto Envers tiene como objetivo permitir el control de versiones sencillo de clases persistentes de JPA. Todo lo que tiene que hacer es anotar su clase persistente o algunas de sus propiedades, que desea versión, con @Versioned. Para cada entidad versionada, se creará una tabla, que mantendrá el historial de los cambios realizados en la entidad. A continuación, puede recuperar y consultar datos históricos sin mucho esfuerzo.

Esto es algo similar a Eric's approach, pero probablemente sea mucho menos esfuerzo. Sin embargo, no sé qué idioma/tecnología utilizas para acceder a la base de datos.

+0

¿Alguien ha utilizado JBoss Envers en un sitio de transacciones de eCom? – boyd4715

4

El único problema con el uso de Triggers es que aumenta la sobrecarga de rendimiento de cualquier inserción/actualización/eliminación. Para una mayor escalabilidad y rendimiento, le gustaría mantener la transacción de la base de datos al mínimo. La auditoría mediante triggers aumenta el tiempo requerido para realizar la transacción y, dependiendo del volumen, puede causar problemas de rendimiento.

Otra forma es explorar si la base de datos proporciona alguna forma de extraer los registros "Rehacer" como en el caso de Oracle. Registros de rehacer es lo que usa la base de datos para volver a crear los datos en caso de que fallen y tengan que recuperarse.

3

Al igual que con un desencadenante (o incluso con), puede hacer que cada transacción desencadene un evento de registro de forma asincrónica y tenga otro proceso (o solo un subproceso) que realmente maneje el registro. Habría muchas formas de implementar esto dependiendo de su aplicación. Sugiero que la aplicación active el evento para que no cause una carga innecesaria en su primera transacción (lo que a veces lleva a bloqueos de los registros de auditoría en cascada).

Además, puede mejorar el rendimiento de la base de datos primaria manteniendo la base de datos de auditoría en una ubicación separada.

1

que utiliza SQL Server, PostgreSQL no, así que no estoy seguro de si esto va a funcionar para usted o no, pero Pop Rivett tenido un gran artículo sobre la creación de un registro de auditoría aquí: Pop rivett's SQL Server FAQ No.5: Pop on the Audit Trail

Construir una auditoría tabla, luego crea un disparador para cada tabla que quieras auditar.

Sugerencia: utilice Codesmith para generar sus desencadenantes.

Cuestiones relacionadas