2010-01-06 22 views
118

Cada vez que necesito diseñar una nueva base de datos paso bastante tiempo pensando en cómo debo configurar el esquema de la base de datos para mantener un registro de auditoría de los cambios.Diseño de base de datos para registro de auditoría

Algunas preguntas que ya se ha pedido aquí sobre esto, pero no me acuerdo en que hay un único mejor enfoque para todos los escenarios:

También me he topado con este interesting article on Maintaining a Log of Database Changes que intenta enumerar los pro y los contras de eac h enfoque. Está muy bien escrito y tiene información interesante, pero ha hecho que mis decisiones sean aún más difíciles.

Mi pregunta es: ¿Existe una referencia que puedo usar, tal vez un libro o algo así como un árbol de decisión que puede referirse a decidir qué manera debo ir sobre la base de algunos variables de entrada, como:

  • la madurez del esquema de base de
  • ¿Cómo se pueden consultar los registros de
  • la probabilidad de que se necesita para volver a crear los registros
  • lo que es más importante: escribir o leer PE rformance
  • Naturaleza de los valores que se está registrando (cadena, números, BLOB)
  • espacio de almacenamiento disponible

Los enfoques que sé que son:

1. Añadir columnas para crear y fecha y de usuario modificado ejemplo

Tabla:

  • Identificación
  • valor_1
  • valor_2
  • VALUE_3
  • created_date
  • modifed_date
  • created_by
  • modified_by

Las principales desventajas: se pierde la historia de las modificaciones. No se puede deshacer después de la confirmación.

2.Inserte sólo las tablas

Table example:

  • Identificación
  • valor_1
  • valor_2
  • VALUE_3
  • de
  • a
  • borrado (booleano)
  • usuario

Principales inconvenientes: ¿Cómo mantener guardadas las claves foráneas? enorme espacio necesario

3. Crear una tabla de historial independiente para cada tabla

ejemplo de tabla de la historia:

  • Identificación
  • valor_1
  • valor_2
  • VALUE_3
  • VALUE_4
  • usuario
  • borrado (booleano)
  • marca de tiempo

Las principales desventajas: tiene que duplicar todas las mesas auditadas. Si el esquema cambia, será necesario migrar todos los registros también.

4. Crear una tabla de historial consolidado para todas las tablas

ejemplo de tabla de la historia:

  • nombre_tabla
  • campo
  • usuario
  • nuevo_valor
  • borrado (booleano)
  • marca de tiempo

Principales inconvenientes: ¿Puedo volver a crear los registros (retroceder) si es necesario fácilmente? La columna new_value debe ser una cadena enorme para que pueda admitir todos los tipos de columna diferentes.

+0

relacionada: http://stackoverflow.com/questions/9852703/store-all-data-changes-with-every-details-stackoverflow-like – Kaii

+0

y lo que sobre el uso de una base de datos de la historia en lugar de tablas? – Jowen

+0

Tal vez podría consultar el diseño de https://github.com/airblade/paper_trail – zx1986

Respuesta

72

Un método que utilizan algunas plataformas wiki es separar los datos de identificación y el contenido que está auditando. Agrega complejidad, pero termina con un registro de auditoría de registros completos, no solo listados de campos que fueron editados, que luego tiene que combinar para darle al usuario una idea de cómo era el registro anterior.

Así, por ejemplo, si has tenido una tabla llamada Oportunidades para rastrear ofertas de venta, usted realmente crear dos mesas separadas:

Oportunidades
Opportunities_Content (o algo así)

La tabla Oportunidades tendría información que usaría para identificar de manera única el registro y alojaría la clave principal que usted consultaría para su oreignar relaciones clave. La tabla Oportunidades_Contenido contendría todos los campos que sus usuarios pueden cambiar y para los cuales le gustaría mantener un registro de auditoría. Cada registro en la tabla Contenido incluiría su propia PK y los datos de fecha modificada y modificada. La tabla Oportunidades incluiría una referencia a la versión actual, así como información sobre cuándo se creó originalmente el registro principal y quién lo hizo.

Aquí está un ejemplo sencillo:

CREATE TABLE dbo.Page( 
    ID int PRIMARY KEY, 
    Name nvarchar(200) NOT NULL, 
    CreatedByName nvarchar(100) NOT NULL, 
    CurrentRevision int NOT NULL, 
    CreatedDateTime datetime NOT NULL 

y el contenido:

CREATE TABLE dbo.PageContent(
    PageID int NOT NULL, 
    Revision int NOT NULL, 
    Title nvarchar(200) NOT NULL, 
    User nvarchar(100) NOT NULL, 
    LastModified datetime NOT NULL, 
    Comment nvarchar(300) NULL, 
    Content nvarchar(max) NOT NULL, 
    Description nvarchar(200) NULL 

que probablemente hacer el PK de la tabla de contenidos una clave de varias columnas de PageID y revisión prevista de revisión fue una Tipo de identidad. Utilizaría la columna Revisión como FK. A continuación, tire del registro consolidado mediante la unión de esta manera:

SELECT * FROM Page 
JOIN PageContent ON CurrentRevision = Revision AND ID = PageID 

Puede haber algunos errores allí arriba ... esto es la parte superior de mi cabeza. Sin embargo, debería darle una idea de un patrón alternativo.

Josh

+5

¿Alguna razón para el voto a favor? –

+8

En términos de buen enfoque de auditoría, pero para la producción, llevará mucho tiempo desarrollar una tabla de auditoría separada para cada tabla en la base de datos, escribir desencadenantes para cada tabla para capturar los cambios y escribirlos en la tabla de auditoría. Además, es un gran desafío desarrollar un único informe de auditoría para todas las tablas, ya que cada tabla de auditoría tiene una estructura diferente. –

+9

Si escribir y mantener scripts para cada tabla es una preocupación para una organización que intenta administrar una base de datos auditada, naturalmente recomendaría que contraten un DBA experimentado o un ingeniero de software altamente experimentado con la experiencia adecuada para crear auditorías bases de datos. – Hardryv

6

No conozco ninguna referencia, pero estoy seguro de que alguien ha escrito algo.

Sin embargo, si el propósito es simplemente tener un registro de lo que sucedió el uso más típico de una auditoría de inicio de sesión, entonces por qué no simplemente mantener todo:

timestamp 
username 
ip_address 
procedureName (if called from a stored procedure) 
database 
table 
field 
accesstype (insert, delete, modify) 
oldvalue 
newvalue 

de suponer que esto se mantiene por un disparador.

+0

Incluso puede hacer una simple: (timestamp, user, sql-command). –

+0

No conozco ninguna forma de conseguirlo dentro del servidor de la base de datos, pero, por supuesto, eso podría hacerse desde fuera con la suficiente facilidad. – wallyk

+2

Me parece que este es el mismo patrón de diseño que la cuarta opción que se muestra en la pregunta original. – givanse

10

Si está utilizando SQL Server 2008, probablemente debería considerar la opción Cambiar captura de datos. Esto es nuevo para 2008 y podría ahorrarle una considerable cantidad de trabajo.

+0

Más información aquí: http://msdn.microsoft.com/en-us/library/cc645858.aspx – RedFilter

+0

aquí está el enlace a la información de seguimiento de cambios de SQL 2012. http://msdn.microsoft.com/en-us/library/bb933994.aspx +1 para usar la funcionalidad integrada, no hay punto para reinventar la rueda. – Chris

+2

@Chris ¿alguna vez lo ha usado usted? De hecho, rastrea todo ... pero ser capaz de obtener información útil es una historia completamente diferente. No puedo usar una rueda de tractor para mi bicicleta. – Jowen

3

Creo que no hay nada como un árbol de decisiones. Dado que algunos de los pros y contras (o los requisitos) no son realmente contables. ¿Cómo se mide la madurez, por ejemplo?

Así que solo alinee los requisitos de su negocio para su registro de auditoría. Intente predecir cómo estos requisitos podrían cambiar en el futuro y genere sus requisitos técnicos. Ahora puede compararlo con los pros y contras y elegir la opción correcta/mejor.

Y esté seguro, no importa cómo decida, siempre habrá alguien que piense que tomó una decisión equivocada. Sin embargo, hiciste tu tarea y justificas tu decisión.

1

vamos a crear una pequeña base de datos de ejemplo para una aplicación de blogs.Se requieren dos tablas:

blog: almacena una ID de publicación única, el título, el contenido y una marca eliminada. audit: almacena un conjunto básico de cambios históricos con un ID de registro, el ID de la publicación del blog, el tipo de cambio (NUEVO, EDITAR o ELIMINAR) y la fecha/hora de ese cambio. El siguiente SQL crea las blog e indexa la columna de borrado:

CREATE TABLE `blog` (
    `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, 
    `title` text, 
    `content` text, 
    `deleted` tinyint(1) unsigned NOT NULL DEFAULT '0', 
    PRIMARY KEY (`id`), 
    KEY `ix_deleted` (`deleted`) 
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='Blog posts'; 

El siguiente SQL crea la tabla audit. Todas las columnas están indexadas y se define una clave externa para audit.blog_id que hace referencia a blog.id. Por lo tanto, cuando ELIMINAMOS físicamente una entrada de blog, también se elimina el historial de auditoría completo.

CREATE TABLE `audit` (
    `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, 
    `blog_id` mediumint(8) unsigned NOT NULL, 
    `changetype` enum('NEW','EDIT','DELETE') NOT NULL, 
    `changetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`), 
    KEY `ix_blog_id` (`blog_id`), 
    KEY `ix_changetype` (`changetype`), 
    KEY `ix_changetime` (`changetime`), 
    CONSTRAINT `FK_audit_blog_id` FOREIGN KEY (`blog_id`) REFERENCES `blog` (`id`) ON DELETE CASCADE ON UPDATE CASCADE 
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; 
Cuestiones relacionadas