¿Cuál es la mejor manera de almacenar cambios en los registros de la base de datos que requieren aprobación antes de ser visibles?

StackOverflow https://stackoverflow.com/questions/103766

  •  01-07-2019
  •  | 
  •  

Pregunta

Necesito almacenar los cambios ingresados ​​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 aún están en estado pendiente, aún mostraría la versión anterior de los datos.¿Cuál sería la mejor manera de almacenar estos cambios en espera de aprobación?

He pensado en varias formas, pero no sé 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 realizar algún tipo de control de versiones de registros en el que almaceno varias versiones de los datos en la tabla y luego siempre extraiga el registro con el número de versión más alto que se haya marcado como aprobado.Eso limitaría la cantidad de tablas adicionales (necesito hacer esto para varias tablas), pero requeriría que realizara un procesamiento adicional cada vez que extraiga un conjunto de registros para asegurarme de obtener los correctos.

¿Alguna experiencia personal con estos métodos u otros que puedan ser buenas?

Actualizar:Sólo para aclarar, en esta situación particular no me interesan tanto los datos históricos.Solo necesito alguna 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, ese se convertirá en el valor mostrado y no será necesario conservar la versión anterior.

¿Alguien probó la siguiente solución donde se almacenan los cambios pendientes de cualquier tabla que necesite rastrearlos como XML en una tabla PendingChanges especial?Cada registro tendría una columna que indicaría para qué tabla fueron los cambios, una columna que tal vez almacenaría la identificación del registro que se cambiaría (nula si es un registro nuevo), una columna de fecha y hora para almacenar cuándo se realizó el cambio y una columna para almacenar el xml del registro modificado (tal vez podría serializar mi objeto de datos).Como no necesito el historial, después de que se aprobara un cambio, la tabla real se actualizaría y el registro PendingChange podría eliminarse.

¿Alguna idea sobre ese método?

¿Fue útil?

Solución

El tamaño es tu enemigo.Si está tratando con una gran cantidad de datos y una gran cantidad de filas, entonces tener el histórico mezclado con el actual lo afectará.También tendrá problemas si une 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, elegiría la tabla histórica separada que actualiza los datos reales en vivo una vez que se aprueba.Es simplemente un limpiador completo.

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

Otros consejos

Definitivamente guárdalos 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 copia.El trabajo adicional para filtrar los datos no aprobados es el tipo de cosas que se supone que deben hacer las bases de datos, si lo piensas bien.Si indexa la columna aprobada, no debería ser demasiado engorroso hacer lo correcto.

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

  1. Mesa principal A
  2. Otra Tabla B que almacena el registro modificado (y por eso es exactamente similar a la primera) + 2 columnas adicionales (una FKey para 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 la necesite).

Recomiendo este enfoque.Maneja todos los escenarios, incluidas las actualizaciones y eliminaciones, con mucha elegancia.

Dado el movimiento de cumplimiento de SOx que se le ha impuesto a la mayoría de las empresas que cotizan en bolsa, tengo bastante experiencia en esta área.Por lo general, he estado usando una tabla separada con una marca de tiempo y cambios pendientes con algún tipo de columna de bandera.El responsable de la administración de estos datos obtiene una lista de cambios pendientes y puede optar por aceptar o no aceptar.Cuando se acepta un dato, utilizo activadores para integrar los nuevos datos en la tabla.Aunque a algunas personas no les gusta el método de activación y prefieren codificarlo en los procesos almacenados.Esto me ha funcionado bien, incluso en bases de datos bastante grandes.La complejidad puede resultar un poco difícil de manejar, 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 la solicitud nunca podrá eliminarse, ya que contiene las "migas de pan", por así decirlo, que son necesarias en caso de que sea necesario rastrear lo que sucedió en una situación particular.Pero en cualquier enfoque, es necesario evaluar los riesgos, como lo que mencioné con los datos contradictorios, y es necesario implementar 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 cambian constantemente, estos datos adicionales en una tabla pueden atascar innecesariamente la solicitud en la tabla y requerirían muchos más detalles sobre cómo están indexando la tabla y sus planes de ejecución.

Crearía una tabla con una bandera y crearía una vista como

 CREATE OR REPLACE VIEW AS 

  SELECT * FROM my_table where approved = 1

Puede ser útil separar las dependencias entre la aprobación y las consultas.Pero puede que no sea la mejor idea si es necesario realizar actualizaciones en la vista.

Mover registros puede tener algunas consideraciones de rendimiento.Pero las tablas particionadas podrían hacer algo bastante similar.

Como se trata de una aplicación web, asumiré que hay más lecturas que escrituras y que desea algo razonablemente rápido, y su resolución de conflictos (es decir, aprobaciones fuera de orden) da como resultado el mismo comportamiento: la última actualización es la que se utiliza.

Ambas estrategias que propone son similares en el sentido de que ambas contienen una fila por conjunto de cambios, tienen que lidiar con conflictos, etc., la única diferencia es si se almacenan 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.

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

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

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

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

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