2008-09-19 8 views
35

Necesito almacenar los cambios introducidos por el usuario en una tabla en particular, pero no mostrar esos cambios hasta que hayan sido vistos y aprobados por un usuario administrativo. Si bien esos cambios todavía están en un estado pendiente, aún mostraría la versión anterior de los datos. ¿Cuál sería la mejor manera de almacenar estos cambios esperando su aprobación?¿Cuál es la mejor manera de almacenar los cambios en los registros de la base de datos que requieren aprobación antes de ser visibles?

He pensado de varias maneras, pero no puedo entender cuál es el mejor método. Esta es una aplicación web muy pequeña. Una forma sería tener una tabla PendingChanges que imite el esquema de la otra tabla, y luego, una vez que se apruebe el cambio, podría actualizar la tabla real con la información. Otro enfoque sería hacer algún tipo de versión de registro donde almaceno múltiples versiones de los datos en la tabla y luego siempre extraer el registro con el número de versión más alto que haya sido marcado como aprobado. Eso limitaría el número de tablas adicionales (tengo que hacer esto para múltiples tablas), pero requeriría que haga un procesamiento adicional cada vez que saque un conjunto de registros para asegurarme de obtener los correctos.

¿Alguna experiencia personal con estos métodos u otros que podrían ser buenos?

Actualización: Solo para aclarar, en esta situación particular no me interesan tanto los datos históricos. Solo necesito una forma de aprobar cualquier cambio que realice un usuario antes de que se publique en el sitio. Entonces, un usuario editará su "perfil" y luego un administrador verá esa modificación y la aprobará. Una vez aprobado, se convertirá en el valor mostrado y no es necesario conservar la versión anterior.

¿Alguien ha intentado la solución a continuación donde almacena los cambios pendientes de cualquier tabla que necesite rastrearlos como XML en una tabla especial PendingChanges? Cada registro tendría una columna que dijera para qué tabla eran los cambios, una columna que tal vez almacenara la identificación del registro que se cambiaría (nulo si es un registro nuevo), una columna de fecha y hora para almacenar cuando se realizó el cambio, y una columna para almacenar el xml del registro modificado (podría tal vez serializar mi objeto de datos). Como no necesito historial, después de aprobar un cambio, la tabla real se actualizaría y el registro de PendingChange podría eliminarse.

¿Alguna idea sobre ese método?

+1

¿Desea almacenar las versiones (en realidad le importan los datos antiguos) o simplemente desea tener los últimos datos aprobados? –

Respuesta

9

El tamaño es tu enemigo. Si se trata de una gran cantidad de datos y un gran número de filas, mezclar el histórico con la corriente lo martillará. También tendrá problemas si se une a otros datos para asegurarse de tener las filas correctas.

Si necesita guardar los datos históricos para mostrar los cambios a lo largo del tiempo, me gustaría ir con la tabla histórica independiente, que actualiza los datos en tiempo real una vez que se aprueba. Es solo un limpiador general.

Si tiene muchos tipos de datos que tendrán este mecanismo pero no necesitan mantener un registro histórico, sugeriría un talbe de cola común para revisar los artículos pendientes, por ejemplo almacenados como xml. Esto permitiría que los administradores solo lean una tabla y le permitirá agregar esta funcionalidad a cualquier tabla en su sistema con bastante facilidad.

+0

¿Cómo manejas las columnas que cambian los nombres? Tiene muchos elementos pendientes y ahora sus datos pendientes no coinciden con la columna en la que se almacenarán. – Sixty4Bit

19

Indistintamente guárdelos en la tabla principal con una columna para indicar si los datos están aprobados o no.

Cuando se aprueba el cambio, no se requiere copiar. El trabajo adicional para filtrar los datos no aprobados es el tipo de cosa que las bases de datos deben hacer, cuando lo piensas. Si indexa la columna aprobada, no debería ser demasiado oneroso para hacer lo correcto.

+1

¡Solo asegúrese de poner un índice en la columna de bandera de aprobación! – Martin

+0

Dame la respuesta :) – jdmichal

+2

Esto es esencialmente una eliminación suave en reversa. – Jim

0

Creo que la segunda forma es la mejor opción, simplemente porque se adapta mejor a varias tablas. Además, el procesamiento adicional sería mínimo, ya que puede crear un índice en la tabla basado en el bit 'aprobado', y puede especializar sus consultas para obtener entradas aprobadas (para ver) o no aprobadas (para aprobar).

3

Dado el movimiento de cumplimiento de SOx que ha sido empujado a la cara de la mayoría de las empresas que cotizan en bolsa, he tenido bastante experiencia en esta área. Usualmente he estado usando una tabla separada con una marca de tiempo de cambios pendientes con algún tipo de columna de bandera. La persona a cargo de la administración de estos datos obtiene una lista de cambios pendientes y puede optar por aceptar o no aceptar. Cuando se acepta una pieza de datos, uso disparadores para integrar los nuevos datos en la tabla. Aunque a algunas personas no les gusta el método desencadenante y prefieren codificarlo en los procesos almacenados. Esto me ha funcionado bien, incluso en bases de datos bastante grandes. La complejidad puede ser un poco difícil de tratar, especialmente cuando se trata de una situación en la que un cambio entra directamente en conflicto con otro cambio y en qué orden procesar estos cambios. La tabla que contiene los datos de solicitud nunca podrá borrarse, ya que contiene las "migas de pan", por así decirlo, que son necesarias en caso de que sea necesario rastrear lo sucedido en una situación particular. Pero en cualquier enfoque, se deben evaluar los riesgos, como lo que mencioné con los datos conflictivos, y se necesita una capa de lógica de negocios para determinar el proceso en estas situaciones.

Personalmente, no me gusta el mismo método de tabla, porque en los casos de almacenes de datos que se cambian constantemente, estos datos adicionales en una tabla pueden atascar innecesariamente la solicitud en la tabla, y requerirían mucho más detalle de cómo está indexando la tabla y sus planes de ejecución.

1

Como esta es una aplicación web, supongo que hay más lecturas que escrituras, y desea algo razonablemente rápido, y la resolución de conflictos (es decir, aprobaciones fuera de servicio) produce el mismo comportamiento - última actualización es el que se usa.

Ambas estrategias que propone son similares, ya que ambas tienen una fila por conjunto de cambios, tienen que lidiar con conflictos, etc., la única diferencia es si almacenar los datos en una tabla o dos. Dado el escenario, dos tablas parecen la mejor solución por razones de rendimiento. También puede resolver esto con una tabla y una vista de los cambios aprobados más recientes si su base de datos lo admite.

1

Otra idea más sería tener tres tablas.

  • Uno sería la tabla principal para guardar los datos originales.
  • El segundo contendría los datos propuestos.
  • El tercero contendría los datos históricos.

Este enfoque le permite retroceder rápida y fácilmente y también le ofrece un seguimiento de auditoría si lo necesita.

4

Trabajo en un dominio bancario y tenemos esta necesidad: que los cambios realizados por un usuario solo deben reflejarse después de que otros los aprueben.El diseño que utilizamos es la siguiente

  1. principal Tabla A
  2. Otra Tabla B que almacena el registro modificado (y así es exactamente similar a los primeros) + 2 columnas adicionales (un FKey a C y un código para indicar el tipo de cambio)
  3. Una tercera tabla C que almacena todos los registros que necesitan aprobación
  4. Una cuarta tabla D que almacena el historial (probablemente no lo necesite).

Recomiendo este enfoque. Maneja todos los escenarios, incluidas las actualizaciones y eliminaciones de forma muy elegante.

+0

¿Cómo trataría las adiciones? – Lucifer

2

me gustaría crear una tabla con una bandera y crear una vista como

CREATE OR REPLACE VIEW AS 

    SELECT * FROM my_table where approved = 1 

Puede ayudar a dependencias separadas entre el aprovement y las consultas. Pero puede que no sea la mejor idea si es necesario realizar actualizaciones a la vista.

El movimiento de registros puede tener algunas consideraciones de rendimiento. Pero las tablas Partitioned podrían hacer algo bastante similar.

Cuestiones relacionadas