Cómo mantener el historial de edición del campo de cadena grande en la base de datos relacional

Una solución en la que estoy trabajando ahora, que funciona bien hasta ahora, implementa el diseño que propuse en la pregunta

Estoy pensando en algo similar a almacenar solo deltas entre la versión actual y la anterior cuando se realiza una edición, y luego reconstruir el historial de versiones de estos deltas programáticamente cuando se solicita, tal vez en el cliente para que los datos enviados por cable minimizado.

Lo más probable es que almacene la última versión como texto completo, ya que me gustaría optimizarla para solicitarla con mayor frecuencia, luego almacenaría una cadena de deltas que van hacia atrás desde la versión actual para reconstruir versiones históricas, cuando y cuando se soliciten.

Compartiré los detalles de mi implementación aquí.

Para crear deltas y usar el para reconstruir el texto completo, estoy usando la fantástica biblioteca google-diff-match-patch . Puede leer la documentación API de implementación agnóstica para comprender mejor los ejemplos de código a continuación, aunque de todos modos es bastante legible.

google-diff-match-patch tiene implementaciones Java y JS para que pueda usarlo para calcular los deltas con Java en el servidor. Elegí convertir cada delta a una Cadena para que pueda almacenarse fácilmente en la base de datos y ser fácilmente consumida por la biblioteca JS en el cliente. Más sobre esto a continuación.

public String getBackwardsDelta(String editedBlogPost, String existingBlogPost) {
    diff_match_patch dmp = new diff_match_patch();
    LinkedList<diff_match_patch.Patch> patches = 
        dmp.patch_make(editedBlogPost, existingBlogPost);
    return dmp.patch_toText(patches);
}

Nota: algo que me llevó un tiempo descubrir fue cómo eliminar la versión oficial de google-diff-match-patch usando maven. No está en el repositorio central de Maven, sino en su propio repositorio en googlecode.com. Solo para tener en cuenta, algunas personas lo bifurcaron y pusieron sus versiones bifurcadas en maven central, pero si realmente desea la versión oficial, puede obtener agregando el repositorio y la dependencia en su pom.xmlsiguiente manera

<repository>
  <id>google-diff-patch-match</id>
  <name>google-diff-patch-match</name>
  <url>https://google-diff-match-patch.googlecode.com/svn/trunk/maven/</url>
</repository>

<dependency>
  <groupId>diff_match_patch</groupId>
  <artifactId>diff_match_patch</artifactId>
  <version>current</version>
</dependency>

Para el front end, paso el último texto completo de la publicación del blog, junto con una cadena de deltas que retrocede en el tiempo representando cada edición, y luego reconstruyo el texto completo de cada versión en el navegador en JS.

Para obtener la biblioteca, estoy usando npm + browserify. La biblioteca está disponible en npm como diff-match-patch . La versión 1.0.0 es la única versión.

getTextFromDelta: function(originalText, delta) {
  var DMP = require('diff-match-patch'); // get the constructor function
  var dmp = new DMP();
  var patches = dmp.patch_fromText(delta);
  return dmp.patch_apply(patches, originalText)[0];
}

Y eso es todo, funciona fantásticamente.

En términos de almacenamiento de las ediciones de las publicaciones del blog, solo uso una tabla BLOG_POST_EDITSdonde almaceno el ID de la publicación del blog, una marca de tiempo de cuándo se realizó la edición (que luego uso para ordenar las ediciones correctamente para hacer la cadena al reconstruir el contenido completo). -las versiones de texto en el cliente), y la diferencia entre la publicación actual del blog en vivo en la BLOG_POSTtabla y la versión editada entrante de la publicación del blog.

Elegí almacenar una 'cadena' de deltas porque se adapta bien a mi caso de uso y es más simple en el extremo del código del servidor. Significa que para reconstruir la versión M de N, tengo que enviar al cliente una cadena de deltas N- (M-1) desde el blog en vivo de texto completo a la versión M. Pero en mi caso de uso sucede que de todas formas, quiero enviar toda la cadena, así que está bien.

Para obtener una eficiencia por cable un poco mejor para solicitar versiones específicas, todos los deltas podrían volver a calcularse desde la nueva versión de publicación de blog editada a cada versión (restaurada) cada vez que se realiza una edición, pero esto significaría más trabajo y complejidad en el servidor.

Respuesta 1

Me gustaría saber cómo mantener el flujo de entrada de un socket y reutilizarlo hasta que la aplicación esté cerca. Lo que hago por ahora es crear un hilo en el método principal. Se supone que este hilo debe mantener ...

Tengo el siguiente código soplar. Traté de encontrar una manera de evitar la fila if (something.isPresent ()) y declarar el algo opcional <Something> también. En cambio, me gustaría encadenar el Opcional ...

Estoy tratando de usar ImageIO.read para leer la imagen de inputstream en un entorno multiproceso. El siguiente es el código, entity = httpResponse.getEntity (); // httpResponse es apache hc response ...

Utilizo la clase Cookies de GWT para generar cookies. Cuando uso las siguientes Cookies.setCookie (LOGIN_COOKIE_NAME, valor, caduca); Todo funciona bien. Verificando la cookie en el navegador conduce ...