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

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *