Pregunta

Tengo un requisito para almacenar todas las versiones de una entidad en una forma fácilmente indexado y se preguntaba si alguien tiene de entrada de qué sistema utilizar.

Sin versiones el sistema es simplemente una base de datos relacional con una fila por, por ejemplo, persona. Si el estado de la persona que cambia de fila se cambia para reflejar esto. Con la entrada de versiones debe actualizarse de manera tal modo que siempre podemos volver a una versión anterior. Si pudiera utilizar una base de datos temporal, esto sería libre y que sería capaz de preguntar '¿cuál es el estado de todas las personas a partir de hoy a las 14:00 de estar en Dublín y 30 años de edad'. Por desgracia, no parece haber ninguna proyectos de código abierto maduros que pueden hacer temporal.

Una forma muy desagradable de hacer esto es simplemente para insertar una nueva fila por cada cambio de estado. Esto conduce a la duplicación, ya que una persona puede tener muchos campos, pero sólo un cambio por actualización. También es bastante lento a continuación para seleccionar la versión correcta para cada persona dada una marca de tiempo.

En teoría, debería ser posible utilizar una base de datos relacional y un sistema de control de versiones para imitar una base de datos temporal, pero esto suena bastante horrible.

Así que me preguntaba si alguien ha encontrado algo similar antes y cómo se acercaban a él?

Actualizar Según lo sugerido por Aaron aquí está la consulta actualmente utilizamos (en MySQL). Es, definitivamente, lento en nuestra mesa con> 200k filas. (Id = clave de la tabla, person_id = Identificación por persona, duplicado si la persona tiene muchas revisiones)

  

selecciona nombre de persona p donde p.id = (seleccione max (id) de persona donde person_id = p.person_id y timestamp <=: timestamp)

Actualizar Parece que la mejor manera de hacerlo es con una base de datos temporal, pero dado que no hay los de código abierto por ahí la siguiente mejor método es almacenar una nueva fila por cada actualización. El único problema es la duplicación de columnas sin cambios y una consulta lenta.

¿Fue útil?

Solución

Hay dos maneras de abordar esto. Ambos asumen que siempre insertar nuevas filas. En todos los casos, debe insertar una marca de tiempo (created) que le dice cuando una fila fue "modificado".

El primer método utiliza un número para contar el número de casos que ya tiene. La clave principal es la clave de objeto más el número de versión. El problema con este enfoque parece ser que se necesita un select max(version) hacer una modificación. En la práctica, esto no suele ser un problema ya que para todas las actualizaciones de la aplicación, primero debe cargar la versión actual de la persona, modificarlo (y el incremento de la versión) y luego insertar la nueva fila. Así que el verdadero problema es que este diseño hace que sea difícil de ejecutar las actualizaciones en la base de datos (por ejemplo, asignar una propiedad a muchos usuarios).

El siguiente método utiliza los enlaces en la base de datos. En lugar de una clave compuesta, le da a cada objeto una nueva clave y tiene un campo replacedBy que contiene la clave de la próxima versión. Este enfoque hace que sea sencillo encontrar la versión actual (... where replacedBy is NULL). Las actualizaciones son un problema, sin embargo, ya debe insertar una nueva fila y actualizar una ya existente.

Para solucionar esto, se puede añadir un puntero hacia atrás (previousVersion). De esta manera, se puede insertar las nuevas filas y luego usar el puntero de nuevo a actualizar la versión anterior.

Otros consejos

Aquí es una encuesta (un poco anticuado) de la literatura sobre las bases de datos temporales: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.91.6988&rep=rep1&type=pdf

Yo recomendaría pasar un buen rato sentado con esas referencias y / o Google Académico para tratar de encontrar algunas buenas técnicas que se adapten a su modelo de datos. Buena suerte!

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