2011-01-23 27 views
19

Solo por el interés de ampliar mis conocimientos, he comenzado a buscar varias opciones de NoSQL. El primero que visité es RavenDB y parece interesante. Todavía estoy tratando de romper mi pensamiento relacional profundo, junto con las rutinas de mantenimiento RDBMS típicas.Cambiar el "esquema" en RavenDB

En mi trabajo cotidiano con Entity Framework pasamos por la rutina de crear scripts de cambios de base de datos, actualizar el modelo de asignación EF, etc. ¿Cómo funciona en cosas NoSQL, especialmente RavenDB? Una vez que una aplicación se ha vuelto a la vida, ¿cómo se hacen cambios en los diversos objetos POCO, etc. y se implementa en producción? ¿Qué sucede con los datos almacenados en las antiguas clases de POCO?

No he profundizado ni he usado Raven DB con ira todavía. Esto puede ser obvio una vez que lo hago, pero me encantaría saberlo de antemano, así que no codifico en una esquina.

Gracias, D.

+0

Seguramente me falta algo, pero IIRC es una base de datos de documentos * schema-less *, por lo que la única respuesta correcta es "no pasa nada". ¿Todavía existen exactamente en el mismo formato en que los pones * en * en ...? –

+1

Muy buen punto ... maldita sea, ¡es difícil sacar mi cabeza del espacio relacional tradicional! – codedog

+0

@codedog Creo que la idea no es necesariamente salir del espacio relacional tradicional, sino darse cuenta de que cada uno es una herramienta con un conjunto diferente de objetivos. Usamos una base de datos relacional y una base de datos NoSQL en nuestra aplicación. No construirías una casa entera con solo un martillo. Del mismo modo, no construirías una casa con solo una sierra. – Brain2000

Respuesta

27

Se quedan como están - propiedades no existentes más serán ignorados durante la carga (y perdieron en el cambio), y las propiedades que faltan van a volver como nulo,

usted recomienda use las operaciones basadas en conjuntos para mantener los datos bajo control con el modelo de objetos.

¡Oh, mírame, ahora estoy en una computadora!

Correcto Así que, básicamente, al trasladarse a un almacén de documentos, tiene razón al reconocer que pierde alguna funcionalidad y obtiene cierta libertad ya que en una base de datos tiene un esquema inicial definido e intenta cargar datos que no funcionan t coincidir con ese esquema dará como resultado un error.

Es importante reconocer, sin embargo, que existe una diferencia entre sin esquema y sin estructura, ya que todos sus documentos contienen su propia estructura (pares clave/valor que denotan el nombre de la propiedad y el valor de la propiedad).

Esto hace que sea útil para el factor de "escribir" y para que sus datos persistan, pero al ser tan fácil cambiar la estructura de su código, puede ser más difícil conciliar eso con su ya persistido datos.

algunas estrategias se presentan en este punto:

  • Haga su estructura inmutable una vez que haya persistido datos, la versión de sus clases
  • permitir la modificación de la estructura, pero el uso de las operaciones basadas en conjuntos para actualizar los datos a coincidir nueva estructura
  • Permitir la modificación de la estructura, y escribir código para hacer frente a las inconsistencias al cargar datos

La tercera es clara Es una mala idea, ya que dará lugar a un código inmanejable, las versiones de tus clases pueden funcionar si solo estás almacenando eventos u otros datos similares, pero no es realmente apropiado para la mayoría de los escenarios, por lo que te queda la opción del medio.

Recomendaría hacer exactamente eso, y siguiendo unas simples reglas en la misma línea que seguiría al tratar con un esquema inicial en una base de datos relacional.

  • utilizar el sistema VCS para determinar los cambios entre las versiones desplegadas scripts de migración
  • escribir que actualizar de una versión a otra
  • Tenga cuidado con los cambios de nombre/extracción de propiedades - como cargar un documento y guardar el documento resultará la pérdida de datos si esas propiedades no existen en el nuevo documento

Etc.

espero que esto es más útil :-)

+1

Me gustaría dar una respuesta más completa, pero estoy en el teléfono –

+1

Me encantaría una respuesta más completa, pero creo que lo que todos ustedes han dicho antes un resumen de todo el punto. Solo estoy tratando de imaginar cómo sería mantener un sitio web ejecutando RavenDB incorporado. Tengo un sitio MVC 3 en proceso, actualmente usando EF4. ¡Muy tentado de arrancar el DAL y reemplazarlo con RavenDB! – codedog

+0

Considérelo hecho –

3

RavenDB serializa sus objetos .NET al formato JSON. No hay esquema

Si agrega algunos objetos a su base de datos, se serializarán. Si agrega algunas propiedades al tipo que está serializando, los objetos que ya ha almacenado perderán esas propiedades.

2

No tiene tanta administración de esquemas como moverla a su código para que nunca haya una discrepancia entre los objetos en su código y los de su base de datos.

La primera parte de los cambios de manejo es asegurarse de que utiliza un serializador que puede manejar los valores faltantes o adicionales; si un campo no está definido en los datos, configúrelo como nulo. Si un campo en los datos no coincide con una propiedad en su objeto, ignórelo.

La mayoría de los cambios se pueden manejar sin más: hay un campo nuevo y es necesario que tenga un valor predeterminado para los registros existentes de todos modos, o hay un campo antiguo que ya no le importa.

Para cambios más complejos como cambiar el nombre/combinar campos o cambiar el formato de datos, agregue un nuevo campo a su objeto sin eliminar los antiguos y haga que su método de carga transfiera datos de los campos anteriores. Cuando guarde el registro, estará en el nuevo formato. Este código puede dejarse en su lugar permanentemente, actualizar datos según sea necesario o puede configurar un proceso de una vez para llamar al mismo código para todos los objetos existentes. Tenga en cuenta que, a diferencia de un script sql, no se requiere un tiempo de inactividad para este tipo de actualización, incluso si lleva mucho tiempo ejecutarlo en un conjunto de datos grande, porque el código puede manejar formatos antiguos y nuevos.

+0

Utiliza la frase "... para asegurarse de usar un serializador ...". ¿Asumo que su consejo no es específico de RavenDB? En mi limitado conocimiento de RavenDB, pensé que tenía un serializador integrado, es decir, no era algo que tuviera que manejar yo mismo. ¿No es eso correcto? – codedog

+0

Sí, eso es para el almacenamiento genérico de documento/objeto NoSQL; uso principalmente JSON en Redis. Con Raven puede especificar un serializador personalizado si lo necesita, pero el estándar le permite establecer campos requeridos/opcionales/ignorados usando atributos. –

3

Este artículo de Ayende describe cómo realizar una migración desde 1 a la versión 2 (en este cambio de una propiedad "Nombre" a las propiedades "Nombre" y "Apellido" caso.

http://ayende.com/blog/66563/ravendb-migrations-rolling-updates

Básicamente, una oyente se ha registrado en el DocumentStore:

documentStore.RegisterListener(new CustomerVersion1ToVersion2Converter()) 

impementation muestra tomada del artículo mencionado anteriormente:

public class CustomerVersion1ToVersion2Converter : IDocumentConversionListener 
{ 
    public void EntityToDocument(object entity, RavenJObject document, RavenJObject metadata) 
    { 
     Customer c = entity as Customer; 
     if (c == null) 
      return; 

     metadata["Customer-Schema-Version"] = 2; 
     // preserve the old Name property, for now. 
     document["Name"] = c.FirstName + " " + c.LastName; 
     document["Email"] = c.CustomerEmail; 
    } 

    public void DocumentToEntity(object entity, RavenJObject document, RavenJObject metadata) 
    { 
     Customer c = entity as Customer; 
     if (c == null) 
      return; 
     if (metadata.Value<int>("Customer-Schema-Version") >= 2) 
      return; 

     c.FirstName = document.Value<string>("Name").Split().First(); 
     c.LastName = document.Value<string>("Name").Split().Last(); 
     c.CustomerEmail = document.Value<string>("Email"); 
    } 
}