DDD, agregados y NoSQL

En la segunda entrada que se publico en este blog sobre RavenDB se hizo una pequeña mención, no demasiado grande la verdad, a la forma en la que tenemos que diseñar nuestros documentos en una base de datos NoSQL. La verda es que esto, no es muy sencillo para aquellos que empiezan a trabajar en una base de datos no relacional, puesto que pasar de diseñar tablas y sus relaciones a documentos sin relaciones es un cambio importante, muy importante diría yo. Todos sabemos que un documento no tiene porque ser una estructura sencilla, sino, que puede ser una agregación de otras entidades, pero ¿cual es el punto en el que rompemos esa agregación o cluster de entidades?

La siguiente imagen nos muestra un posible diseño de un documento para una estructura de producto, backlog items, task, sprint etc…en el que se ha decidido crear un único tipo de documento que aglutine esta información, la imagen se ha extraído del Management Studio de Raven DB, pero lo mismo se aplicaría a cualquier base de datos documental como MongoDB etc..

Untitled

Independientemente de la que los atributos del documento sean más o menos reales o que falte algo de información ¿es este un buen diseño de documento? ¿Deberíamos hacer documentos más pequeños y, si es así, cual es la referencia/técnica que debemos utilizar?

La respuesta que yo siempre intento dar es asimilar el diseño de documentos con los mismos conceptos que utilizamos en DDD con Aggregate Roots. Cuando uno empieza a trabajar con agg roots ( un concepto facil de explicar pero dificil de poner en la práctica ), tiene  prácticamente las mismas dudas e inquietudes, y casi siempre, estas se resuelven pensando en invariants y consistency boundary en vez de elementos composicionales, como por ejemplo podría haber sido nuestro caso en el que se ha pensado en la composición de un producto sobre cualquier otro concepto. Si en vez de forma composicional pensaramos en consistencia transaccional y la preservación de invariantes nos daríamos cuenta de como un agregado tan grande como el nuestro provocaría infinidad de transacciones erroneas puesto que en el negocio es habitual que varias personas por ejemplo se dedicaran a incluir nuevos backlogitems de forma concurrente, etc etc…

Por supuesto, la otra alternativa a hacer un agregado de grandes dimensiones como este, sería definir agregados por entidad, es decir, múltiples agregados, pero.. ¿es esta la vía correcta? Aquí en realidad, incurrimos en el mismo error que el anterior, no pensar en invariantes  consistencia. Sigamos con el ejemplo, ¿tiene sentido separar un producto de sus backlogItems? ¿hay algún invariante que mantener? Si lo piensa, seguramente podríamos separarlo sin más problemas y esto, incurriría en muchas ventajas para nosotros puesto que los errores de concurrencia que teníamos antes desaparecerían fácilmente.. pero, siguiendo con un ejemplo similar ¿tiene sentido separar un pedido y sus lineas de pedido?¿hay invariantes y/o consistencia transaccional que mantener?.

Seguramente ya ha notado la diferencia entre ámbos casos ¿verdad?¿ seguro?  Pues bien, esta es la forma de pensar a la hora de diseñar los agregados, pensando en los invariantes y la consistencia, intentando siempre que sean lo más finos posible.

 

El trabajo con los documentos es un nuevo aprendizaje para muchos, y durante este aprendizaje, como en todos, cometeremos errores. Espero que con este posts y con las consiguientes referencias bibliográficas el número de errores a cometer sea el mínimo posible. Por supuesto, dependiendo de su NoSQL documental preferida tendrá ventajas a la hora de trabajar el diseño de documentos y su trabajo, el manejo de la concurrencia o las referencias podrían ser unas de las características a revisar en su motor.

 

Referencias

Excelente serie sobre diseño de agregados de Vaughn Vernon:http://www.shiftmethod.com/publications

 

Domain Driven Design, Aggregates: http://domaindrivendesign.org/node/88

 

Saludos

Unai

EF 4.3 Beta 1: más madera….y un pequeño extra…

Cuando se publique este post habrá salido ya el anuncio de la primera beta de ADO.NET EF 4.3 en el blog del equipo de producto de ADO.NET. Los que me leeis con asiduidad sabréis que si solamente es para poner una reseña no suelo escribir una entrada o sea que trataré de dar mi punto de vista sobre esta nueva beta y algunas cosillas extras que no salen publicadas en los diferentes walkthrough.

Bien, antes de empezar con las novedades, que enumeraremos a continuación, es importante decir que esta será la última versión de EF hasta la llegada de EF 5.0 con la siguiente entrega de .NET Framework, en la que el código base, es decir, System.Data.Entity, por fin abrirá más puertas para introducir más y más importantes mejoras. Como acabamos de comentar, de entre las novedades mñas importantes que podemos encontrar en esta version tenemos los siguientes elementos, para el resto de información, revisar la entrada del grupo de producto aquí.

 

  • Inclusión del paquete de Migraciones dentro del código base de EntityFramework.dll
  • Resueltos un par de bugs, revisar el post del grupo de producto
  • Una nueva sección de configuración que nos permitirá establecer inicializadores y configurar la DefaultConnectionFactory que utilizaremos por defecto

 

Migraciones es ahora parte de EF

 

Como ya comentamos en esta anterior entrada desde esta versión EF incluye por defecto el paquete de migraciones, sin tener, como hasta ahora que incluir en NuGet EntityFramework.Migrations como hasta ahora. En realidad, el funcionamiento es el mismo que hasta ahora, pero, con unos pequeños ligeros cambios en los comandos de power shell y la eliminación de la convención IncludeMetadataConvention. Como siempre, lo mejor es verlo todo en la práctica o sea que vamos a ello. Crearemos, como hacemos habitualmente, un proyecto tonto de demo que nos permitirá ir viendo cosillas.

 

Lo primero será incluir el paquete de EF 4.3, puesto que es beta, al igual que se ha hecho con otros paquetes, tenemos que incluir en el comando de instalación la opcion IncludePreRelease aunque también suelen funcionar PreRelease y Pre simplemente.

1

Una vez incluído el paquete de la beta, crearemos nuestra unidad de trabajo, un ejemplo sencillo, tal y como hacemos habitualmente:

 








































 

Tal y como sabréis todos a estas alturas, si utilizaramos la unidad de trabajo anterior, se nos generaría una nueva base de datos para el mode2lo dado, ahora, este proceso será el mismo, pero con un importante cambio y es que el proceso de creación de la base de datos se hace utilizando el API de Migrations, para ello basta con fijarse que ya no tenemos la tabla de metadata típica y sin embargo, en las tablas de sistema podemos ver una nueva llamada __MigrationHistory, tal y como se ven en la imagen de la derecha.

 

Bueno, aunque esto sea así, por defecto, el sistema de migraciones no está habilitado en nuestros cambios de dominio, para ello, tenemos que ejecutar el comando Enable-Migrations. Este comando, tiene el mismo efecto que tenía en anteriores versiones incluir el paquete de migraciones, es decir, nos agrega una nueva carpeta llamada Migrations en la que tendremos la configuración del sistema de migraciones y se incluirá el código de las distintas migraciones que vayamos haciendo. En realidad aquí no hay nada nuevo a lo que ya conocíamos, aunque para ser sincero tampoco he revisado el conjunto de propiedades que DbMigrationsConfiguration pone a nuestra disposición.

 

 

 

 

 

Bien, una vez habilitadas las migraciones pasaremos a crear(actualizar) la base datos, otra vez, como ya sabíamos tenemos el comando Update-Database con sus diferentes opciones, os recomiendo mirar el get-help Update-Database –detailed para una completa información de todo lo que podemos hacer. Por ahora, al habilitar las migraciones ya tendremos la base de datos generada y por lo tanto, el comando nos dirá que no tiene tareas pendientes o sea que empezaremos agregando una nueva propiedad a Blog, por ejemplo CreationDate, como vemos en el siguiente fragmento.

 














 

Una vez agregada esta propiedad, agregaremos una migración, para ello, usaremos otra vez el ya conocido comando Add-Migration, el cuál, incluye  en la carpeta de migraciones el código de la nueva migración, que yo he llamado AddedCreationDate y que contiene algo similar a lo siguiente:

 
































































Por supuesto, también, como ya sabrá de anteriores entradas podemos hacer otras tareas como la creación de índices etc, como vemos en la lista de métodos que DbMigration pone a nuestra disposición:

 

  • AddColumn
  • AddForeignKey
  • AddPrimaryKey
  • AlterColumn
  • CreateIndex
  • CreateTable
  • DropColumn
  • DropForeignKey
  • DropIndex
  • DropPrimaryKey
  • DropTable
  • MoveTable
  • RenameColumn
  • RenameTable
  • Sql

La nueva sección de configuración

 

Como comentábamos  antes,aquí va el punto extra, y es que EF 4.3 pone a nuestra disposición a una nueva sección de configuración, EntityFrameworkSection, gracias a la cual podremos configurar desde el DefaultConnectionFactory que queremos tener por defecto ( antes teníamos que recurrir a Database.DefaultConnectionFactory ) hasta los inicializadores que queremos tener por defecto. A continuación os pongo un fragmento de una sección de configuración sobre un contexto de trabajo en el que se establece un inicializador y en la que además se establece una factoria de conexión por defecto.

 

4

 






































 

Como veis el equipo de ADO.NET está trabajando duro y esto es algo que podemos ver de forma temprana gracias a que los paquetes de EF nuevos no forman parte del Framework. Os imaginais que pasaría si EF se fuera a un modelo como el de MVC en el que no tienen una dependencia con el framework… ummmm

 

Saludos

Unai

P&P y CQRS: Guía + implementación de ejemplo

Bueno, una entrada cortita, la gente de Patterns and Practices han lanzado una encuesta valorando los intereses y conocimientos de la gente referidos a CQRS. El caso es que Grigori, Eugenio, Cesar de la torre y compañia están preparando una guia y probablemente una implementación de ejemplo de CQRS y quieren preguntarnos por nuestras inquietudes y preferencias antes de continuar…

 

Si te gusta CQRS entra en la encuesta y participa, si te interesa o crees que es bueno esta nueva guia lo mismo, participa aquí

 

Gracias

Unai

EF 4.X: Sql Federations

Para los que estéis al dia de todo lo que ocurre con Windows Azure y las distintas features que están poniendo habréis visto que entre node.js, linux y otras lindezas se está planeando liberar una release de Sql Azure Federation, vamos, lo que toda la vida se ha llamado la capacidad de “sharding” . Sino me equivoco, Ibon estará más enterado que yo y podría corregirme, esta feature saldra en el Q4 del 2011, es decir a finales de año. Llegados aquí, a muchos, yo entre ellos, se preguntarán si nos cambia algo la vida en cuanto al desarrollo y por supuesto, los que utilizamos un ORM como EF nos lo preguntamos con mayor preocupación todavía.

 

Después de leer la documentación y demás sobre como está formado Azure Federations la cosa se vuelve un poquito preocupante, sobre todo porque por ejemplo tendremos que renunciar a las capacidades que nos da EF para autogenerarnos una base de datos a partir del modelo, puesto que ahora, tendremos que especificar en la creación elementos como la federación etc, a mayores de crear la federación. Es decir, antes de generar la base de datos deberíamos tener cosas como las siguientes:



 

 

Bien, esto de por si ya implica una pequeña restricción, la pena, es que esta no es la única, puesto que en nuestras consultas tendremos que hacer un pequeño trabajo para establecer sobre que miembro del sharding pueden trabajar. Por suerte para nosotros, el grupo Windows Azure Customer Advisory Team ( tiene narices que la web sea php )  ha creado un pequeño manual de como debemos de trabajar que sin duda nos será de mucha ayuda el cual lo podeís encontrar aquí

Espero que os sea de interés…

Saludos

Unai