Estoy tratando de encontrar un enfoque para un proyecto, donde un usuario puede editar registros y poder ver versiones anteriores de esos registros. Aquí hay un esquema de ejemplo simplificado, usando una lista:
TABLE list (
id int auto_increment primary key,
user_id int,
title varchar(255)
);
TABLE list_tasks (
id int auto_increment primary key,
list_id int,
title varchar(255),
order int,
is_complete tinyint
);
Por lo tanto, un usuario puede ingresar y realizar varias ediciones en la lista (es decir, agregar o eliminar tareas, reordenar tareas, marcar algunas completas, cambiar el nombre de algunas, etc.), luego guardarlas. En este punto, me gustaría generar una 'versión 2' de la lista y las tareas, y hacer que puedan ver versiones anteriores, pero cuando acceden a la lista, siempre obtienen la última versión.
¿Existe un patrón de enfoque / diseño común para tratar los datos de versiones de esta manera en una base de datos MySQL?
mysql
versioning
GSto
fuente
fuente
Respuestas:
Es bastante común querer hacer eso en una base de datos. Aunque le está dando un giro en el sentido de que desea realizar un seguimiento de una revisión de una lista de elementos.
Una forma de hacerlo podría ser alterar la estructura, como
Cuando el usuario guarda su lista, cree una nueva revisión en la
revisions
tabla anterior y asigne ese valor a los elementos de la listalist_tasks
y luego a la identificación de revisiónlists
para marcar esa identificación como la revisión 'actual'. Cuando el usuario edite los elementos, no edite los elementos existentes; en su lugar, inserte otros nuevos con un nuevo ID de revisión y actualice lalist
tabla con esa revisión para marcarla como la actual.Luego, para enumerar los elementos actuales, enumere los elementos del ID de revisión actual especificado en la
lists
tabla. Para buscar versiones anteriores, puede obtener una lista de revisiones anteriores de las listas de la tabla de revisiones y luego enumerar los elementos individuales en función de esa identificación.fuente
Esta solución utiliza una tabla de auditoría separada. Tiene pros y contras. Es posible que prefiera eliminar los registros antiguos de su tabla principal. La mejora del rendimiento puede ser insignificante.
Agregue los siguientes campos a cada tabla auditada:
Deberá actualizar estos campos cada vez que cambien los datos. CurrentVersion se incrementa en 1 (podría usarse como una forma de bloquear un registro, pero esa es otra pregunta). IsDeleted proporciona una "eliminación suave" para que pueda ser referenciada en el futuro.
Tablas de auditoría separadas Cada tabla debe tener una versión correspondiente de _Archive o _History de la tabla. Probablemente no sea necesario indexarlos de la misma manera. Obviamente, no se aplicará un solo campo de clave primaria. Debería poder crear una clave compuesta del campo ID y UpdateDateTime.
Usando un disparador (Esto abordará los cambios realizados dentro o fuera de su código. Puede decidir si esto funciona para su situación) u otra codificación, cuando se agrega, actualiza o elimina un registro, se coloca una copia del registro en el archivo / tabla de historial. Se mantienen todas las versiones y otros campos de auditoría. Esto le dirá qué hicieron los usuarios y cuándo. La tabla se puede comparar a sí misma para ver cuándo se modificó un registro o para ver tendencias.
He visto que esto funciona bien en los últimos años. Me gustaría escuchar sobre inconvenientes que tal vez no esté considerando.
fuente
Te sugiero que leas este artículo bien detallado.
https://blog.jondh.me.uk/2011/11/relational-database-versioning-strategies/comment-page-1/#comment-373850
Otro enfoque es tener una columna version_id en su tabla y un indicador 'actual' que especifique qué fila es la actual. Cada vez que necesite una actualización, puede insertar una nueva fila y establecer el indicador 'actual' de la versión existente en 0 / falso y la fila recién agregada en 1.
De esta manera, puede crear una vista que muestre solo aquellos con el conjunto de banderas actual.
fuente