Pregunta

Tengo una pregunta sobre las dos columnas adicionales (timeCreated, timeLastUpdated) para cada registro que vemos en muchas soluciones. Mi pregunta: ¿Hay una alternativa mejor?

Escenario: tiene una base de datos enorme (en términos de tablas, no de registros), y luego el cliente llega y le pide que agregue " marca de tiempo " al 80% de tus tablas.

Creo que esto se puede lograr utilizando una tabla separada (TIMESTAMPS). Esta tabla tendría, además de la columna de marca de tiempo obvia, el nombre de la tabla y la clave principal para la tabla que se está actualizando. (Supongo que aquí usas un int como clave principal para la mayoría de tus tablas, pero el nombre de la tabla probablemente sea una cadena).

Para imaginar esto supongamos este escenario básico. Tendríamos dos tablas:

PAGO: - (sus registros habituales)
TIMESTAMP: - {timestamp actual} + { TABLE_UPDATED , id_of_entry_updated , timestamp_type }

Tenga en cuenta que en este diseño no necesita esos dos " extra " columnas en su objeto de pago nativo (que, por cierto, podrían hacerlo a través de su solución ORM) porque ahora está indexando por TABLE_UPDATED y id_of_entry_updated . Además, timestamp_type le dirá si la entrada es para inserción (por ejemplo, " 1 "), actualización (por ejemplo, " 2 "), y cualquier otra cosa que desee agregar, como " eliminación " ;.

Me gustaría saber qué piensa acerca de este diseño. Estoy más interesado en las mejores prácticas, lo que funciona y las escalas con el tiempo. Referencias, enlaces, entradas de blog son más que bienvenidos. Sé de al menos una patente (pendiente) que trata de resolver este problema, pero parece que los detalles no son públicos en este momento.

Saludos, Eduardo

¿Fue útil?

Solución

Mientras esté en ello, también registre al usuario que hizo el cambio.

La falla con el diseño de la tabla separada (además del rendimiento de la combinación resaltado por otros) es que supone que cada tabla tiene una columna de identidad para la clave. Eso no siempre es cierto.

Si usa SQL Server, la nueva versión 2008 admite algo que llaman Change Data Capture que debería quitarle gran parte del dolor del que estás hablando. Creo que Oracle también puede tener algo similar.


Actualización: Al parecer, Oracle lo llama lo mismo que SQL Server. O más bien, SQL Server lo llama lo mismo que Oracle, ya que la implementación de Oracle fue lo primero;)
http://www.oracle.com/technology/oramag/ oracle / 03-nov / o63tech_bi.html

Otros consejos

He utilizado un diseño en el que cada tabla que se auditaría tenía dos tablas:

create table NAME (
  name_id int,
  first_name varchar
  last_name varchar
  -- any other table/column constraints
)

create table NAME_AUDIT (
  name_audit_id int
  name_id int
  first_name varchar
  last_name varchar
  update_type char(1) -- 'U', 'D', 'C'
  update_date datetime
  -- no table constraints really, outside of name_audit_id as PK
)

Se crea un activador de base de datos que rellena NAME_AUDIT cada vez que se hace algo para NAME . De esta forma, tendrá un registro de cada cambio realizado en la tabla y cuándo. La aplicación no tiene conocimiento real de esto, ya que se mantiene mediante un activador de base de datos.

Funciona razonablemente bien y no requiere ningún cambio en el código de la aplicación para implementarlo.

Creo que prefiero agregar las marcas de tiempo a las tablas individuales. Unirse a su tabla de marca de tiempo en una clave compuesta, una de las cuales es una cadena, será más lento y, si tiene una gran cantidad de datos, eventualmente será un problema real.

Además, muchas veces cuando mira las marcas de tiempo, es cuando está depurando un problema en su aplicación y querrá los datos allí mismo, en lugar de tener que unirse siempre a la otra tabla.

La ventaja del método que sugiere es que le brinda la opción de agregar otros campos a su tabla TIMESTAMP, como el seguimiento del usuario que realizó el cambio. También puede realizar un seguimiento de las ediciones en los campos confidenciales, por ejemplo, ¿quién ha cambiado el precio de este contrato?

Registrar los cambios de registro en un archivo separado significa que puede mostrar múltiples cambios en un registro, como:

mm / dd / aa hh: mm: ss Añadido por XXX mm / dd / aa hh: mm: ss Campo PRECIO modificado por XXX, mm / dd / aa hh: mm: ss Registro eliminado por XXX

Una desventaja es el código adicional que realizará las inserciones en su tabla TIMESTAMPS para reflejar los cambios en sus tablas principales.

Si configura el sello de tiempo para que se ejecute fuera de los activadores, se puede registrar cualquier acción que pueda activar un activador (¿Lecturas?). También puede haber algunas ventajas de bloqueo.

(Toma todo eso con un grano de sal, no soy un gurú de DBA o SQL)

Sí, me gusta ese diseño y lo uso con algunos sistemas. Por lo general, alguna variante de:

LogID  int
Action varchar(1)     -- ADDED (A)/UPDATED (U)/DELETED (D)
UserID varchar(20)    -- UserID of culprit :)
Timestamp datetime    -- Date/Time
TableName varchar(50) -- Table Name or Stored Procedure ran
UniqueID int          -- Unique ID of record acted upon
Notes varchar(1000)   -- Other notes Stored Procedure or Application may provide

Una pesadilla con su diseño es que cada inserción, actualización o eliminación tendría que golpear esa tabla. Esto puede causar problemas importantes de rendimiento y bloqueo. Es una mala idea generalizar una tabla como esa (no solo para las marcas de tiempo). También sería una pesadilla sacar los datos de.

Si su código se interrumpiría en el nivel de la GUI al agregar campos que no quiere que el usuario vea, está escribiendo incorrectamente el código en su GUI, que debe especificar solo el número mínimo de columnas que necesita y nunca seleccionar *.

Creo que las combinaciones adicionales que tendrás que realizar para obtener las marcas de tiempo serán un golpe de rendimiento leve y un dolor en el cuello. Aparte de eso no veo ningún problema.

Hicimos exactamente lo que hiciste Es excelente para el modelo de objetos y la capacidad de agregar nuevos sellos y diferentes tipos de sellos a nuestro modelo con un código mínimo. También estábamos rastreando al usuario que hizo el cambio, y gran parte de nuestra lógica se basó en gran medida en estos sellos. Se despertó muy bien.

Un inconveniente es informar y / o mostrar muchos sellos diferentes en la pantalla. Si lo haces de la manera que lo hicimos, causó muchas uniones. Además, los cambios de finalización fueron un dolor.

Nuestra solución es mantener una " Transacción " tabla, además de nuestra " Sesión " mesa. Todas las instrucciones de ACTUALIZACIÓN, INSERTAR y BORRAR se administran a través de una " Transacción " objeto y cada una de estas instrucciones SQL se almacena en la " Transacción " tabla una vez que se ha ejecutado con éxito en la base de datos. Esta " Transacción " La tabla tiene otros campos, como transactiontType (I para INSERT, D para DELETE, U para UPDATE), transactionDateTime, etc, y una clave externa " sessionId " ;, que nos dice finalmente quién envió la instrucción. Incluso es posible, a través de algún código, identificar quién hizo qué y cuándo (Gus creó el registro el lunes, Tim cambió el precio unitario el martes, Liz agregó un descuento adicional el jueves, etc.).

Los pros para esta solución son:

  1. puedes decir " qué quién y cuándo " y mostrarlo a tus usuarios. (necesitarás algo de código para analizar las sentencias de SQL)
  2. si sus datos se replican y la replicación falla, puede reconstruir su base de datos a través de esta tabla

Los contras son

  1. 100 000 actualizaciones de datos por mes significan 100 000 registros en Tbl_Transaction
  2. Finalmente, esta tabla tiende a ser el 99% del volumen de su base de datos

Nuestra elección: todos los registros de más de 90 días se eliminan automáticamente cada mañana

Philippe,

No elimine simplemente los que tienen más de 90 días, muévalos primero a una base de datos separada o escríbalos en un archivo de texto, haga algo para preservarlos, simplemente muévalos fuera de la base de datos de producción principal.

Si alguna vez se reduce a esto, la mayoría de las veces es un caso de " él con la mayor cantidad de documentación gana " ;!

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