Algunos compañeros de trabajo y yo entramos en un debate sobre la mejor manera de almacenar datos históricos. Actualmente, para algunos sistemas, uso una tabla separada para almacenar datos históricos y mantengo una tabla original para el registro activo actual. Entonces, digamos que tengo mesa FOO. Bajo mi sistema, todos los registros activos irán en FOO, y todos los registros históricos irán en FOO_Hist. El usuario puede actualizar muchos campos diferentes en FOO, por lo que quiero mantener una cuenta precisa de todo lo actualizado. FOO_Hist contiene exactamente los mismos campos que FOO con la excepción de un HIST_ID de incremento automático. Cada vez que se actualiza FOO, realizo una instrucción de inserción en FOO_Hist similar a: insert into FOO_HIST select * from FOO where id = @id
.
Mi compañero de trabajo dice que este es un mal diseño porque no debería tener una copia exacta de una tabla por razones históricas y simplemente debería insertar otro registro en la tabla activa con un indicador que indique que es para fines históricos.
¿Existe un estándar para tratar con el almacenamiento de datos históricos? Me parece que no quiero saturar mis registros activos con todos mis registros históricos en la misma tabla, considerando que puede haber más de un millón de registros (estoy pensando a largo plazo).
¿Cómo usted o su empresa manejan esto?
Estoy usando MS SQL Server 2008, pero me gustaría mantener la respuesta genérica y arbitraria de cualquier DBMS.
fuente
No creo que haya una forma estándar particular de hacerlo, pero pensé que incluiría un posible método. Trabajo en Oracle y en nuestro marco interno de aplicaciones web que utiliza XML para almacenar datos de aplicaciones.
Usamos algo llamado Modelo Maestro - Detalle que, en su forma más simple, consiste en:
La tabla maestra, por ejemplo, a
Widgets
menudo se llama solo con un ID. A menudo contendrá datos que no cambiarán con el tiempo / no son históricos.Tabla de detalles / historial, por ejemplo, llamada que
Widget_Details
contiene al menos:Entonces, esencialmente, una entidad comienza teniendo 1 fila en el maestro y 1 fila en el detalle. El detalle que tiene una fecha de finalización NULL y STATUS_CONTROL de 'C'. Cuando se produce una actualización, la fila actual se actualiza para tener END_DATETIME de la hora actual y status_control se establece en NULL (o 'A' si se prefiere). Se crea una nueva fila en la tabla de detalles, aún vinculada al mismo maestro, con status_control 'C', la identificación de la persona que realiza la actualización y los nuevos datos almacenados en la columna XMLDATA.
Esta es la base de nuestro modelo histórico. La lógica de Crear / Actualizar se maneja en un paquete Oracle PL / SQL, por lo que simplemente le pasa a la función la ID actual, su ID de usuario y los nuevos datos XML e internamente realiza todas las actualizaciones / inserciones de filas para representar eso en el modelo histórico . Las horas de inicio y finalización indican cuándo está activa esa fila de la tabla.
El almacenamiento es barato, generalmente no BORRAMOS datos y preferimos mantener un seguimiento de auditoría. Esto nos permite ver cómo se veían nuestros datos en un momento dado. Al indexar status_control = 'C' o usar una Vista, el desorden no es exactamente un problema. Obviamente, sus consultas deben tener en cuenta que siempre debe usar la versión actual (NULL end_datetime y status_control = 'C') de un registro.
fuente
Creo que tu enfoque es correcto. La tabla histórica debe ser una copia de la tabla principal sin índices, asegúrese de tener también la marca de tiempo de actualización en la tabla.
Si prueba el otro enfoque lo suficientemente pronto, enfrentará problemas:
fuente
En SQL Server 2016 y versiones posteriores , hay una nueva característica llamada Tablas temporales que tiene como objetivo resolver este desafío con el mínimo esfuerzo del desarrollador . El concepto de tabla temporal es similar a la Captura de datos de cambio (CDC), con la diferencia de que la tabla temporal ha abstraído la mayoría de las cosas que tenía que hacer manualmente si estaba usando CDC.
fuente
Cambie la captura de datos: https://docs.microsoft.com/en-us/sql/relational-databases/track-changes/about-change-data-capture-sql-server?view=sql-server-2017
Es compatible con SQL Server 2008 R2, podría haber sido compatible con SQL Server 2008.
fuente
Esta pregunta es bastante antigua, pero la gente todavía está trabajando en este tema. así que si está utilizando Oracle, puede estar interesado en flashback de Oracle : http://docs.oracle.com/cd/B28359_01/appdev.111/b28424/adfns_flashback.htm
fuente
Solo quería agregar una opción que comencé a usar porque uso Azure SQL y lo de varias tablas fue demasiado engorroso para mí. Agregué un disparador de inserción / actualización / eliminación en mi tabla y luego convertí el cambio antes / después a json usando la función "FOR JSON AUTO".
Eso devuelve una representación JSON para el registro antes / después del cambio. Luego almaceno esos valores en una tabla de historial con una marca de tiempo de cuándo ocurrió el cambio (también almaceno el ID para el registro actual de preocupación). Utilizando el proceso de serialización, puedo controlar cómo se rellenan los datos en caso de cambios en el esquema.
Aprendí sobre esto en este enlace aquí
fuente
¿Podrías dividir las tablas no?
"Estrategias de tabla e índice particionadas con SQL Server 2008 Cuando una tabla de base de datos crece a cientos de gigabytes o más, puede ser más difícil cargar nuevos datos, eliminar datos antiguos y mantener índices. Solo el tamaño de la tabla hace que tales operaciones demoren mucho más. Incluso los datos que deben cargarse o eliminarse pueden ser muy considerables, lo que hace que las operaciones INSERT y DELETE en la tabla no sean prácticas. El software de base de datos Microsoft SQL Server 2008 proporciona particiones de tabla para hacer que tales operaciones sean más manejables ".
fuente
La verdadera pregunta es ¿necesita usar datos históricos y datos activos juntos para informar? Si es así, manténgalos en una tabla, particione y cree una vista para registros activos para usar en consultas activas. Si solo necesita verlos ocasionalmente (para investigar problemas legales o algo así), póngalos en una tabla separada.
fuente
JOIN
dos tablas en un par de informes históricos o es más difícil modificar cada inserción / actualización / eliminación de cada tabla para tener en cuenta las preocupaciones históricas? En realidad, un registro de auditoría incluiría incluso los datos actuales en la tabla del historial, por lo que la tabla actual ni siquiera debería ser necesaria en un informe.Otra opción es archivar los datos operativos sobre una base [diaria | por hora | lo que sea]. La mayoría de los motores de bases de datos admiten la extracción de datos en un archivo .
Básicamente, la idea es crear un trabajo programado de Windows o CRON que
Muchos motores de bases de datos SQL vienen con una herramienta que puede usarse para este propósito. Por ejemplo, cuando se usa MySQL en Linux, el siguiente comando se puede usar en un trabajo CRON para programar la extracción:
fuente
Conozco esta publicación anterior, pero solo quería agregar algunos puntos. El estándar para tales problemas es lo que funciona mejor para la situación. Comprender la necesidad de dicho almacenamiento, y el uso potencial de los datos históricos / auditoría / seguimiento de cambios es muy importante.
Auditoría (propósito de seguridad) : use una tabla común para todas sus tablas auditables. defina la estructura para almacenar el nombre de la columna, antes del valor y después de los campos de valor.
Archivo / Histórico : para casos como el seguimiento de la dirección anterior, número de teléfono, etc., crear una tabla separada FOO_HIST es mejor si su esquema de tabla de transacción activa no cambia significativamente en el futuro (si su tabla de historial tiene que tener la misma estructura). si anticipa la normalización de la tabla, la adición / eliminación de columnas de cambio de tipo de datos, almacene sus datos históricos en formato xml. defina una tabla con las siguientes columnas (ID, Fecha, Versión del esquema, XMLData). esto manejará fácilmente los cambios de esquema. pero tiene que lidiar con xml y eso podría introducir un nivel de complicación para la recuperación de datos.
fuente
Puede usar la función de Auditoría de Servidor MSSQL. Desde la versión SQL Server 2012 encontrará esta característica en todas las ediciones:
http://technet.microsoft.com/en-us/library/cc280386.aspx
fuente
Puede crear vistas materializadas / indexadas en la tabla. Según sus requisitos, puede realizar una actualización total o parcial de las vistas. Por favor, vea esto para crear mview y log. ¿Cómo crear vistas materializadas en SQL Server?
fuente