Formas de versionar documentos generados por el usuario

8

Tengo un documento en línea que esencialmente se almacena en la base de datos como una cadena XML.

Estoy pensando en una forma de implementar versiones del documento para el usuario. Para que el usuario pueda volver a las versiones anteriores del documento.

actualizar En mi caso es una aplicación web con cientos de miles de usuarios. Un usuario puede almacenar una cantidad ilimitada de documentos. El XML para el documento se almacena en el campo de blobs de MySQL, por lo que no es pequeño. Eventualmente necesito limitar los límites de alguna manera, pero ese es un tema diferente en conjunto.

¿Hay una forma estándar de abordar esto? ¿Debo almacenar solo las diferencias entre versiones? ¿Qué otras cosas debo tener en cuenta?

desarrollador
fuente
1
La pregunta interesante aquí es: ¿tiene un infraestructura de base de datos MYSQL existente donde los datos deben integrarse (especialmente un sistema a escala para esa cantidad de usuarios)? La sugerencia de RCS de Crazy Eddie no parece integrarse fácilmente en dicho sistema.
Doc Brown
¿Cuál es el modelo de seguridad? ¿Asumo que los documentos de cada usuario son privados?
Michael
@ Michael Sí, los documentos de cada usuario son privados
ejemplo,
@DocBrown Sí, tengo una tabla Mysql db existente donde estos documentos xml se almacenan en este momento.
dev.e.loper
@ dev.e.loper: supongo que el servidor de base de datos no aplica la privacidad, ¿verdad? El número de usuarios que menciona indica que está hablando de una solución de servidor web escalado. La pregunta que se plantea aquí es: ¿quiere / debe tener que mantener los datos XML en la base de datos, o puede elegir una tecnología diferente para esa parte de los datos?
Doc Brown

Respuestas:

13

¿Por qué no usar un repositorio de control de código fuente? Ocupará menos espacio de almacenamiento, hará todo lo que desee actualmente y le permitirá ampliar fácilmente el concepto a ramas, etiquetas, etc., todo lo que obtiene de un RCS. ¿Por qué reinventar la rueda?

Edward extraño
fuente
¿A qué te refieres exactamente? ¿Estás diciendo instalar SVN en mi servidor y usar api para almacenar esos archivos?
dev.e.loper
¿Hay un cuello de botella en alguna parte de este enfoque? Por ejemplo, si tengo 50,000 usuarios guardando / versionando su trabajo. El repositorio de control de código fuente necesita manejar versiones para esos 50,000 ¿correcto?
dev.e.loper
El OP está hablando de una base de datos (supongo, una existente). No conozco ningún sistema de control de fuente que se integre fácilmente en un esquema de base de datos existente.
Doc Brown
@ dev.e.loper: un RCS decente, incluido SVN, debería ser capaz de manejar tantos usuarios.
Edward Strange
5

Como está haciendo esto en una base de datos, la forma más fácil de versionar su cadena XML sería crear una nueva tabla de Historial con las siguientes columnas:

  • ID de historia
  • Nueva cadena XML (columna opcional)
  • Cadena XML antigua
  • Insertar marca de tiempo

Inserte una fila en esta tabla de Historial antes de actualizar la fila en la tabla de cadenas XML.

Gilbert Le Blanc
fuente
Si actualiza la fila en la tabla de cadenas XML, no hay forma de obtener la versión anterior. Todo lo que puede hacer es ver un historial de fechas de cambio. Tendría que hacer inserciones en lugar de actualizaciones ... preferiblemente de diffs.
Edward Strange
@CrazyEddie: la versión anterior (versión anterior) está en la tabla Historial. Las diferencias no son necesarias para un documento.
Gilbert Le Blanc
"Las diferencias no son necesarias": no sabe qué tan grande es el documento, con qué frecuencia se modifica y si el OP quizás no significó "un documento por usuario". Así que "no se necesitan diferencias" es solo una suposición descabellada. Sin embargo, te di +1, ya que creo que tu respuesta apunta en la dirección correcta. Pero puede mejorarlo explicando mejor qué contendrán esas columnas "versión nueva" y "versión anterior" (cadenas XML, referencias a ID de historial anteriores, ¿o algo más?)
Doc Brown
@Doc Brown: Y no sabes con qué frecuencia se requiere la versión anterior de la cadena XML, sin mencionar el tiempo y el esfuerzo para escribir un motor de diferencias, que también tiene que diferir. Ni siquiera sabe si la base de datos hace compresión de cadenas de texto. Arreglé las referencias de columna.
Gilbert Le Blanc
@GilbertLeBlanc: Ambos no lo sabíamos (cuando el OP escribió su primera versión de la pregunta), y por eso no habría escrito "diffs son necesarios" o "diffs no son necesarios" aquí. Solo sugeriría no comenzar con una solución diff más complicada si una solución no diff más simple puede ser suficiente. Supongo que eso es lo que quisiste decir.
Doc Brown
3

¿Hay una forma estándar de abordar esto?

Para un enfoque basado en estándares, eche un vistazo a la extensión Delta-V a WebDAV (una extensión ampliamente admitida a HTTP). Delta-V agrega versiones a WebDAV y se describe en RFC 3253 .

Caleb
fuente
1

Una forma relativamente simple es incrementar una identificación de revisión en cada guardado y guardar el nuevo documento xml bajo esa nueva identificación de revisión.

tabla: docs

doc_id | name          | current_revision
   1   | Shopping List |       5         

tabla: doc_revisions

doc_id | revision | timestamp | xml_blob
  1    |    1     | 2012...   |
  1    |    2     | 2012...   |
  1    |    3     | 2012...   |
  1    |    4     | 2012...   |
  1    |    5     | 2012...   |

También puede considerar almacenar los archivos xml por separado en el sistema de archivos. Puede modificar la tabla doc_revisions con una URL / ruta al archivo en lugar de un blob. Eso permitirá que su base de datos maneje volúmenes mucho más altos en un solo servidor porque la base de datos no será físicamente tan grande (podría mover los documentos a un servidor diferente) y estaría quitando la carga de recuperación de documentos del servidor de base de datos.

Personalmente, no almacenaría las diferencias de archivo. Más bien, almacenaría la nueva revisión completa del archivo cada vez. El almacenamiento es barato y no es necesario complicar las cosas. La funcionalidad 'diff' podría implementarse más adelante si finalmente resulta que realmente la necesita. Si almacena diffs, tenga en cuenta que podría introducir un montón de complejidades inesperadas, por ejemplo, si necesita buscar el texto de los documentos.

Gran maestro B
fuente
En cuanto al almacenamiento de diferencias de archivos, estoy investigando el almacenamiento de diferencias con la ayuda de la biblioteca diff-match-patch code.google.com/p/google-diff-match-patch
dev.e.loper
1

¿Por qué no imitar un registro de base de datos?

Básicamente, los cambios se marcan cronológicamente como transacciones. Para una base de datos de documentos, una transacción consistiría en una marca de tiempo y una marca de tiempo diffs en lugar de una entrada de fila de tabla, pero el concepto funciona igual. Prácticamente de la misma manera que funcionan los sistemas de control de versiones.

Para mantener las cosas ágiles, mantenga una copia en caché de la versión actual. Si alguien necesita retroceder en el tiempo, puede revertir (es decir, revertir) las transacciones hasta que alcancen el historial solicitado. La idea es que la copia en caché no cambia hasta que se realiza una operación de guardar.

Para mantener la coherencia, también debe tener en cuenta las reversiones. Siguiendo lo que ya describí, digamos que el usuario retrocede 5 versiones. 5 transacciones se aplicarían inversamente en orden cronológico inverso a la versión actual, pero cuando se guarda ese estado, la transacción se almacena como una diferencia de ese estado en comparación con la versión actual.

Básicamente, la historia nunca se reescribe, solo se reutiliza para crear nuevas versiones.

Evan Plaice
fuente