¿El mejor diseño para una tabla de base de datos de registro de cambios / auditoría? [cerrado]

114

Necesito crear una tabla de base de datos para almacenar diferentes registros de cambios / auditorías (cuando algo se agregó, eliminó, modificó, etc.). No necesito almacenar información particularmente detallada, así que estaba pensando en algo como:

  • id (para evento)
  • usuario que lo activó
  • nombre del evento
  • descripción del evento
  • marca de tiempo del evento

¿Me estoy perdiendo de algo? Obviamente, puedo seguir mejorando el diseño, aunque no planeo hacerlo complicado (crear otras tablas para tipos de eventos o cosas así está fuera de discusión, ya que es una complicación para mi necesidad).

rcphq
fuente
Leí tu respuesta y me sorprende que nadie hable de Derecho. Sé que algunas leyes o documentos de buenas prácticas explican cómo DEBEMOS implementar una tabla de auditoría (de solo lectura). Pero no tengo más información que esta. Solo sé que existe. Estoy pensando en la pista de auditoría en CFR 21 parte 11.
Bastien Vandamme

Respuestas:

70

En el proyecto en el que estoy trabajando, el registro de auditoría también comenzó con un diseño muy minimalista, como el que describiste:

event ID
event date/time
event type
user ID
description

La idea era la misma: simplificar las cosas.

Sin embargo, rápidamente se hizo evidente que este diseño minimalista no era suficiente. La auditoría típica se reducía a preguntas como esta:

Who the heck created/updated/deleted a record 
with ID=X in the table Foo and when?

Entonces, para poder responder a estas preguntas rápidamente (usando SQL), terminamos teniendo dos columnas adicionales en la tabla de auditoría.

object type (or table name)
object ID

Fue entonces cuando el diseño de nuestro registro de auditoría realmente se estabilizó (desde hace algunos años).

Por supuesto, la última "mejora" funcionaría solo para tablas que tuvieran claves sustitutas. ¿Pero adivina que? ¡Todas nuestras tablas que vale la pena auditar tienen esa clave!

Yarik
fuente
El único problema que he tenido con este diseño (una pista de auditoría basada en una "descripción") es la localización del idioma utilizado en ese campo.
Sam Wilson
@Sam No veo ese problema, si el mensaje es generado por el sistema, solo use una clave aquí para la cadena de traducción;
JCM
4
@Hiru: Cuando "mezcla" dos o más conceptos distintos en una columna, la mayoría de las veces va a ser contraproducente, tarde o temprano. Por ejemplo, si "mezcla" el tipo de evento y el tipo de objeto, afectaría consultas como "muéstrame registros para todos los objetos del tipo dado" y "muéstrame registros para todos los eventos de un tipo dado" (las consultas serían más complicado y probablemente funcionaría mucho más lento).
Yarik
3
Además de estas columnas, se puede tener una columna adicional para descripción estructurada / carga útil de evento estructurado . Esta columna contendría detalles del evento (de cualquier complejidad) en un formato legible por computadora, XML / JSON. Fácil de serializar, consultar (al menos en Postgres / MSSQL), razonar.
turdus-merula
1
@Benjamin: La respuesta está en el modelo de dominio (también conocido como modelo de negocio). Si el modelo permite la creación simultánea de entidades (por ejemplo, como parte de una transacción lógica), entonces no veo ningún problema en tener varios registros con exactamente la misma marca de tiempo. Por ejemplo, si la creación de una orden de compra (como una transacción) puede incluir la creación de N artículos de pedido, entonces todos los registros de registro 1 + N correspondientes tendrían la misma marca de tiempo. El análisis posterior de dicho registro podría aprovechar esto, tratando estos registros 1 + N no como independientes sino como elementos de una transacción lógica. Espero que esto tenga sentido.
Yarik
24

También registramos los valores antiguos y nuevos y la columna de la que proceden, así como la clave principal de la tabla que se audita en una tabla de detalles de auditoría. ¿Piensa para qué necesita la tabla de auditoría? No solo desea saber quién hizo un cambio y cuándo, sino que, cuando ocurre un cambio incorrecto, desea una forma rápida de recuperar los datos.

Mientras diseña, debe escribir el código para recuperar datos. Cuando necesita recuperarse, generalmente es apresurado, es mejor estar ya preparado.

HLGEM
fuente
1
Esto es realmente bueno No entiendo por qué la gente ignora las últimas publicaciones.
Maddy.Shik
3
El abastecimiento de eventos es un enfoque alternativo para proporcionar funcionalidad de retroceso mientras se mantiene el historial.
Sam
23

Hay varias cosas más que podría querer auditar, como nombres de tablas / columnas, computadora / aplicación desde la cual se realizó una actualización y más.

Ahora, esto depende de cuán detallada sea la auditoría que realmente necesite y en qué nivel.

Comenzamos a construir nuestra propia solución de auditoría basada en disparadores, y queríamos auditar todo y también tener una opción de recuperación a mano. Esto resultó ser demasiado complejo, por lo que terminamos aplicando ingeniería inversa a la herramienta de terceros basada en disparadores ApexSQL Audit para crear nuestra propia solución personalizada.

Consejos:

  • Incluir valores antes / después

  • Incluya 3-4 columnas para almacenar la clave principal (en caso de que sea una clave compuesta)

  • Almacene los datos fuera de la base de datos principal como ya sugirió Robert

  • Dedique una cantidad de tiempo decente a la preparación de informes, especialmente aquellos que pueda necesitar para la recuperación

  • Planifique el almacenamiento del nombre del host / aplicación; esto puede resultar muy útil para rastrear actividades sospechosas

Kenneth Hampton
fuente
2
¿Por qué lo harías con ingeniería inversa en lugar de comprarlo?
Jowen
1
más control sobre el producto
Tebe
1
Espero que no te hayan demandado.
Clasificador
9

Hay muchas respuestas interesantes aquí y en preguntas similares. Las únicas cosas que puedo agregar por experiencia personal son:

  1. Coloque su tabla de auditoría en otra base de datos. Idealmente, desea una separación de los datos originales. Si necesita restaurar su base de datos, realmente no desea restaurar la pista de auditoría.

  2. Desnormalizar tanto como sea razonablemente posible. Quiere que la tabla tenga la menor cantidad posible de dependencias de los datos originales. La tabla de auditoría debe ser simple y rápida para recuperar datos. No hay combinaciones ni búsquedas sofisticadas en otras tablas para acceder a los datos.

Robert4Real
fuente
8
¿Los datos no normalizados serían realmente más rápidos de leer en comparación con los datos normalizados con índices apropiados? (¿No resultaría toda la duplicación en la lectura de más datos del HDD?)
Sam
4

Lo que tenemos en nuestra mesa: -

Primary Key
Event type (e.g. "UPDATED", "APPROVED")
Description ("Frisbar was added to blong")
User Id
User Id of second authoriser
Amount
Date/time
Generic Id
Table Name

La identificación genérica apunta a una fila de la tabla que se actualizó y el nombre de la tabla es el nombre de esa tabla como una cadena. No es un buen diseño de base de datos, pero es muy útil. Todas nuestras tablas tienen una sola columna de clave sustituta, por lo que esto funciona bien.

WW.
fuente
2
¿Qué representa "cantidad"?
turdus-merula
Es una aplicación financiera, por lo que es el valor en dólares de la cosa que se autoriza, etc.
WW.
4

En general, la auditoría personalizada (crear varias tablas) es una mala opción. Los activadores de la base de datos / tabla se pueden desactivar para omitir algunas actividades de registro. Las tablas de auditoría personalizadas se pueden alterar. Pueden ocurrir excepciones que reduzcan la aplicación. Sin mencionar las dificultades para diseñar una solución robusta. Hasta ahora veo casos muy simples en esta discusión. Necesita una separación completa de la base de datos actual y de cualquier usuario privilegiado (DBA, Desarrolladores). Todos los RDBMS convencionales brindan servicios de auditoría que incluso los DBA no pueden deshabilitar, manipular en secreto. Por lo tanto, la capacidad de auditoría proporcionada por el proveedor de RDBMS debe ser la primera opción. Otra opción sería un lector de registro de transacciones de terceros o un lector de registro personalizado que empuja la información descompuesta al sistema de mensajería que termina en algunas formas de Audit Data Warehouse o controlador de eventos en tiempo real. En resumen: Solution Architect / "Hands on Data Architect" necesita involucrarse en el destino de dicho sistema en función de los requisitos. Por lo general, es algo demasiado serio solo para entregarlo a un desarrollador para que lo solucione.

Joel Mamedov
fuente
3

Hay muchas maneras de hacer esto. Mi forma favorita es:

  1. Agregue un mod_usercampo a su tabla de origen (el que desea registrar).

  2. Cree una tabla de registro que contenga los campos que desea registrar, más un campo log_datetimey seq_num. seq_numes la clave principal.

  3. Cree un disparador en la tabla de origen que inserte el registro actual en la tabla de registro cada vez que se cambie cualquier campo monitoreado.

Ahora tienes un registro de cada cambio y quién lo hizo.

JosephStyons
fuente
Entonces ... ¿qué se supone que debe hacer el campo mod_user?
conny
1
Decirle quién hizo el cambio. El código de actualización debe incluir algo para configurar ese campo para el usuario actual.
JosephStyons
¿Qué pasa con las eliminaciones, entonces? Si elimina una fila, ¿cómo maneja el valor de la columna mod_user?
Kenn Cal
@KennCal Triggers puede usar tablas virtuales, puede ver los datos antes y después dentro del mismo disparador. No importa la operación. stackoverflow.com/questions/6282618/…
Renan Cavalieri
2
@KennCal Tiene razón, el activador de eliminación deberá almacenar esa información por usted. Sin embargo, el diablo está en los detalles: si está utilizando la autenticación SQL, el disparador puede simplemente ejecutar [seleccione CURRENT_USER]. Si se trata de una aplicación cliente, el código del cliente debe anunciar quién es. Si es una llamada a la API, entonces el usuario que borra debe ser un parámetro obligatorio para la llamada.
JosephStyons
1

Según el principio de separación:

  1. Las tablas de datos de auditoría deben estar separadas de la base de datos principal. Debido a que las bases de datos de auditoría pueden tener una gran cantidad de datos históricos, tiene sentido desde el punto de vista de la utilización de la memoria mantenerlos separados.

  2. No utilice desencadenantes para auditar toda la base de datos, porque terminará con un desorden de diferentes bases de datos para admitir. Tendrá que escribir uno para DB2, SQLServer, Mysql, etc.

Bhagat007
fuente