El auge de las bases de datos no-sql sigue siendo un hecho fácilmente constatable cada vez que hablamos con alguien del sector de la informática.
A parte de otras motivaciones, las bases de datos no-sql pueden ser entendidas como una solución a los históricos problemas de escalabilidad de las bases de datos relacionales.
Muchos profesionales tienen en mente algunos motores muy conocidos como Cassandra, Neo4J o MongoDB pero sigue habiendo bastante confusión, sobretodo a la hora de utilizar queries más complejas y es cierto que para persistir datos no muy conectados entre si, el no-sql da buenos resultados pero…(y esto es lo importante)
con el no-sql es a la hora de las joins cuando hay que pensar muy bien como diseñamos el modelo lógico
Existen unos 6 tipos diferentes de bases de datos no-sql aunque lo más utilizados son estos 3 tipos de orientaciones:
- Clave / Valor
- Documentos
- Grafos
Después de este preámbulo, quisiera comentar algunas consideraciones sobre el modo en que diseñamos el modelo de datos. Para ello he pensado en uno de los motores más utilizados para guardar datos en forma de documentos, vamos a hablar de la agregación en MongoDB.
MongoDB, tan de moda ultimamente, cuenta con la bienvenida particularidad de que se puede integrar con un ODM, por ejemplo Doctrine
El ODM (Object Document Mapping) tiene como cometido implementar una capa de abstracción de la persistencia.
Los problemas que presenta la composición y agregación en MongoDB son basicamente 2:
- Duplicación de datos: cuando agregamos una entidad a otra en una propiedad, mongo puede persistir los datos directamente en la entidad padre o puede crear otra entidad y relacionar por índice. Si necesitamos listar la entidad hijo y a la vez acceder rapidamente a los datos padre-hijo podemos facilmente incurrir en una duplicación.
- Disponibilidad: en entidades con propiedades-entidades, para devolver el objeto padre debidamente poblado hay que contruir en run-time de lectura.
¿ Como solucionar esto y componer de manera óptima para que no nos penalicen los joins ?
- Las relaciones que no sean de * : 1 ó de * : * las denormalizamos en un sólo documento sin duplicar datos.
- Computar el agregado en runtime de lectura con el aggregation framework de mongodb, y pasar a materialización en escritura o asíncrono sólo si demostramos una alta carga en el futuro. Lo importante es hacerlo sobretodo modular, para que se pueda cambiar rápido en el futuro.
- Hacerlo en modo asíncrono, que es introducir colas, una buena opción aunque sea sólo en memoria: https://github.com/pedroteixeira/camel-stomp
- Hay otra opción que comento por curiosidad, materializar la agregación usando un each, pero si no está bien tuneado es costoso.
- Materializar la Join, es decir, crear una vista materializada de la consulta, afinando bastante el map-reduce.
- Prueba con CQRS, a grandes rasgos sería decir una base de datos para lectura y otra para escritura.
Señalar también de pasada, y esto es un artículo que me gustaría pedirle a Christian Ciceri para que analizara a fondo el tema, que
el modelo arquitectural más optimo para enfrentarse a este tipo de problemas, parece ser el Domain Driven Design
o mejor dicho, ¡ un Distributed Domain Driven Design en toda regla ! Ya sabéis… ¡ a desempolvar los libros ! 🙂
Finalmente, recuerda que no solo tienes el no-sql, sino que puedes combinar tu modelo de datos con el relacional de toda la vida. Si necesitas hacer operaciones complejas sobre datos y esta complejidad puede crecer en el tiempo, te recomiendo que montes una tabla sql en tu tecnología preferida.
Si os interesa el tema, ahí van algunos enlaces interesantes:
Eager fetch de relaciones de join:
http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/priming-references.html
Resultados para solo lectura – scalar:
http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/query-builder-api.html#disabling-hydration
Materialización de join, una estratégia interesante en caso de mal rendimiento:
Operativamente, en mongodb:
http://blog.knoldus.com/2013/02/03/joins-now-possible-in-mongodb/
Como siempre, cualquier duda o comentario interesante es bienvenido !