Diseño de debate:¿cuáles son las buenas formas de almacenar y manipular versiones de los objetos?[cerrado]

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

Pregunta

Estoy intencionalmente, dejando esta bastante vago en el primero.Estoy buscando para la discusión y qué cuestiones son importantes, más de lo que yo estoy buscando respuestas duras.

Estoy en el medio del diseño de una aplicación que hace algo como la gestión de la cartera.El diseño que tengo hasta ahora es

  • Problema:un problema que necesita ser resuelto
  • Solución:una propuesta de solución a uno o más problemas
  • Relación:una relación entre los dos problemas, dos soluciones, o un problema y una solución.Además se dividen en:
    • Padre-hijo - de algún tipo de categorización / árbol de la jerarquía de
    • Superposición - el grado en el que dos soluciones o dos problemas de abordar realmente el mismo concepto
    • Direcciones - el grado en el cual un problema se aborda una solución

Mi pregunta es acerca de la naturaleza temporal de estas cosas.Los problemas surgen, entonces se desvanecen.Las soluciones de una espera de la resolución de fecha, pero que puede ser modificada a medida que se desarrollan.El grado de una relación puede cambiar con el tiempo como los problemas y soluciones evolucionan.

Entonces, la pregunta:¿cuál es el mejor diseño para el control de versiones de estas cosas, así que me puede conseguir tanto una corriente y una perspectiva histórica de mi cartera?

Más tarde:quizás debería hacer de esto una más pregunta específica, aunque @Eric Barba, la respuesta es digno de una.

He considerado tres diseños de base de datos.Voy suficiente de cada uno para mostrar sus inconvenientes.Mi pregunta es:que elegir, o puede usted pensar en algo mejor?

1:Los problemas (y por separado, Soluciones) son auto-referenciales en el control de versiones.

table problems
  int id | string name | text description | datetime created_at | int previous_version_id

  foreign key previous_version_id -> problems.id

Esto es problemático porque cada vez que quiero una nueva versión, tengo que duplicar la fila completa, incluyendo la larga description columna.

2:Crear un nuevo tipo de Relación:Versión.

table problems
  int id | string name | text description | datetime created_at

Esto simplemente se mueve la relación de los Problemas y de las Soluciones de tablas en las Relaciones de la tabla.Mismo problema de duplicación, pero tal vez un poco más "limpios" como ya tengo un resumen de la Relación concepto.

3:El uso de más de Subversion-como la estructura;mover todos los problemas y la Solución de los atributos en una tabla independiente y la versión de ellos.

table problems
  int id

table attributes
  int id | int thing_id | string thing_type | string name | string value | datetime created_at | int previous_version_id

  foreign key (thing_id, thing_type) -> problems.id or solutions.id
  foreign key previous_version_id -> attributes.id

Esto significa que para cargar la versión actual de un Problema o de la Solución que tengo para recuperar todas las versiones del atributo, ordenarlos por fecha y, a continuación, utilizar la más actual.Que no podría ser terrible.Lo que parece realmente malo para mí es que no puedo escribir a revisar estos atributos en la base de datos.Que value la columna tiene que estar libre de texto.Puedo hacer el name de columna de una referencia en un attribute_names tabla que tiene un type en la columna, pero que no la fuerza el tipo correcto en el attributes tabla.

aún más tarde:respuesta a @Eric Barba comentarios acerca de la multi-tabla de claves foráneas:

Ay, lo que yo he descrito es simplista:sólo hay dos tipos de Cosas (Problemas y Soluciones).La verdad es que tengo unos 9 o 10 diferentes tipos de Cosas, así que yo tendría 9 o 10 columnas de claves foráneas en virtud de su estrategia.Yo quería usar una sola tabla de la herencia, pero las Cosas que tienen tan poco en común que podría ser muy es un desperdicio de combinar en una sola tabla.

¿Fue útil?

Solución

Hmm, suena algo como este sitio...

En cuanto a la base de datos diseño de un sistema de control de versiones como SVN, donde en realidad nunca hacen las actualizaciones, solo inserta (con un número de versión) cuando las cosas cambian, podría ser lo que usted necesita.Esto es denominado MVCC, Multi-Valor de Control de Concurrencia.Un wiki es otro buen ejemplo de esto.

Otros consejos

@Gayo

foreign key (thing_id, thing_type) -> problems.id or solutions.id

Tenga cuidado con estos tipos de "multidireccional" claves foráneas.Mi experiencia me ha demostrado que el rendimiento de la consulta sufre dramáticamente cuando su condición de combinación tiene que comprobar el tipo antes de averiguar qué tabla a unirse en.No parece ser tan elegante, pero que aceptan valores null

problem_id and solution_id 

funciona mucho mejor.

Por supuesto, el rendimiento de las consultas también sufren con un MVCC diseño cuando usted tiene que agregar el de verificación para obtener la versión más reciente de un registro.La desventaja es que usted nunca tendrá que preocuparse acerca de contención con las actualizaciones.

¿Qué piensa usted acerca de esto:

problemas de la tabla
int id | nombre de la cadena de texto | descripción | datetime created_at

tabla problems_revisions
int revisión | int id | nombre de la cadena de texto | descripción | datetime created_at
clave externa id -> problemas.id

Antes de las actualizaciones, usted tendrá que realizar un adicional de insertar en la revisión de la tabla.Esta inserción es rápida, sin embargo, esto es lo que usted tiene que pagar por

  1. el acceso eficiente a la versión actual - seleccionar los problemas, como de costumbre
  2. un esquema que es intuitiva y cercana a la realidad que desea modelo
  3. las uniones entre tablas en el esquema mantener eficiente
  4. el uso de un número de revisión por busines transacción que usted puede hacer control de versiones sobre los registros de la tabla como SVN hace más de archivos.

Supongo que habrá

Opción 4:el híbrido

Mover la Cosa común atributos en una sola-la herencia de la tabla, a continuación, añadir una custom_attributes tabla.Esto hace que el extranjero claves más simple, se reduce la duplicación, y permite la flexibilidad.No soluciona los problemas de seguridad de tipo para los atributos adicionales.También se añade un poco de complejidad, ya que hay dos formas para que una Cosa tenga un atributo de ahora.

Si description y otros grandes campos de permanecer en las Cosas de la tabla, sin embargo, también no resolver la duplicación-problema de espacio.

table things
  int id | int type | string name | text description | datetime created_at | other common fields...
  foreign key type -> thing_types.id

table custom_attributes
  int id | int thing_id | string name | string value
  foreign key thing_id -> things.id

Es una buena idea elegir una estructura de datos que hace preguntas comunes que pedir que el modelo es fácil de responder.Lo más probable es que usted está interesado en la posición actual de la mayoría de las veces.En la ocasión, se quiere profundizar en la historia para resolver problemas específicos y soluciones.

Me hubiera tablas para el problema, la solución, y la relación que representa la posición actual.También habrá un problem_history, solution_history, etc tabla.Estos serían niño tablas de problema, pero también contienen columnas adicionales para VersionNumber y EffectiveDate.La clave sería (ProblemId, VersionNumber).

Cuando se actualiza un problema, habría que escribir los valores anteriores en la problem_history tabla.Punto en el tiempo de las consultas son por lo tanto posible como usted puede escoger el problem_history registro que es válido-en una fecha determinada.

Donde he hecho esto antes, también he creado una vista de la UNIÓN problem y problem_history como este es a veces útil en diversas consultas.

Opción 1 hace que sea difícil para la consulta de la situación actual, como todos sus datos históricos se mezclan con los datos actuales.

Opción 3 va a ser malo para el rendimiento de las consultas y desagradable código en contra de como vas a tener acceso a un montón de filas para lo que debería ser una simple consulta.

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