To Embed or reference? (Parte II)

Standard

Hola todos.

En esta ocasión les traigo la segunda (y espero que la última) parte de mi post anterior. Por si no lo recuerdan pueden consultarlo en el siguiente enlace:

To embed or reference? (Parte I)

Les recomiendo que si les interesa lo que escribo, y se disponen a leer esta publicación, primero le den un vistazo a la anterior para que tengan idea de lo que estoy hablando (escribiendo).

Bien. En la publicación previa les explicaba un poco el proceso de normalización para modelos de datos relacionales y les decía que, aunque en Mongodb no se normaliza como tal, es necesario hacer la analogía para entender y quizá poder contestar nuestra pregunta principal “Embeber o referenciar”.

Sabemos que mongodb trabaja con documentos, los cuales son estructuras un tanto “más libres” que las tablas. Esto abre más posibilidades para quién este diseñando un modelo de datos. Y precisamente esta libertad es lo que en cierto punto puede llegar a representar un problema. Más adelante nos daremos cuenta por qué.

Los documentos en Mongo son modelados en JSON (Java Script Object Notation) y guardados en BSON (Binary JSON). Esto significa que son una especie de diccionario de clave-valor, donde el valor puede ser de los siguientes tipos:

  • Tipos primitivos JSON
  • Tipos primitivos BSON (DateTime, Regex, etc)
  • Arreglos de valores
  • Objetos de clave-valor
  • Null

Si quisiéramos guardar en documentos los datos de nuestras tablas anteriores (por eso les decía que checaran el otro post) tendríamos las siguientes 2 opciones:

//database document

{

“id”: 10,

“user_name”: “Sosa24”,

“e_mail”: “sosa@something.com”,

“phone_numbers”: {“8664728324”, “6378648369”}

}

 

//contact document

{

“id”: 10,

“user_name”: “Sosa24”,

“e_mail”: “sosa@something.com”,

}

 

//numbers document

{“contact_id”: 10, “phone_number”: “8664728324”}

{“contact_id”: 10, “phone_number”: “6378648369”}

 

 

 

En la primera opción estamos embebiendo documentos, o dicho de otra manera, poniendo un documento dentro de otro. En nuestro caso tenemos un documento para cada contacto o usuario, (o como gusten llamarle), y dentro de él un documento que contiene los números de teléfono relativos a ese usuario.

En la segunda opción se muestra un modelo de documentos referenciados. Si se dan cuenta tenemos un documento que contiene la información del usuario y un documento por cada número de teléfono asociado a ese usuario, la relación entre ambos, obviamente se da a través de los id.

Enseguida analizaremos las características de cada uno de estos 2 casos, y a partir de esto se podrá tomar un decisión sobre qué tipo de estructura de documentos, (referenciados o embebidos) nos conviene más implementar.

Una de las razones para elegir los documentos embebidos en las relaciones de uno a muchos es la localización de los datos. Con esto me refiero a la localización física (en disco), al tener todo en un solo documento estamos ahorrando tiempo en la búsqueda de información.

También es importante mencionar que mongo no permite implementar un JOIN, tal cual como se haría en una base de datos relacional. Lo que representa un punto a favor para la realización de consultas en documentos embebidos.

Veamos un ejemplo:

Si quisiéramos consultar los números de teléfono de un usuario en particular, usando documentos referenciados tendríamos que hacer lo siguiente:

contact_info = db.contacts.find_one({‘id’: 10})

number_info = list(db.numbers.find({‘contact_id’: 10})

Lo cual nos es óptimo en cuestión de tiempo, ya que se tienen que hacer 2 búsquedas, cuando usando documentos embebidos solo haríamos una.

Otra razón para preferir embeber documentos, es que nos garantizan atomicidad y aislamiento. Obviamente estas características tienen mayor relevancia y significado dentro de ambientes distribuidos, donde se requiere que los datos se encuentren en forma consistente.

Como mongo no implementa transacciones, se vuelve un tanto trivial el ejecutar un conjunto de operaciones y garantizar que una vez hecho esto, nuestros datos sigan consistentes. En los documentos embebidos esto NO nos afecta, pues si queremos borrar cierta información, por ejemplo un usuario, sabemos que toda su información está dentro del mismo documento y con un DELETE será suficiente. En cambio en los documentos relacionales o referenciados, tendríamos que borrar primero el documento de usuario y después ir a borrar los documentos que contienen su número (o números) de teléfono. Si por nuestra mala suerte sucede algo y borramos solo el documento del usuario, y dejamos los documentos con su(s) numero(s) telefónicos, ya tendríamos información inconsistente, lo cual no es bueno :c (nadie quiere a las inconsistentes, así que no le hagas daño a tu base de datos).

No crean que todo es malo con los documentos referenciados, aunque ya les echamos mucha tierra, es hora de que veamos cuáles son sus ventajas.

Uno de los puntos principales a favor de los documentos referenciados, es la FLEXIBILIDAD que brindan en el rendimiento de las consultas. Cuando tratamos con estructuras de datos complejas, que podrían descender varios niveles en los documentos embebidos (con descender niveles me refiero a un documento dentro de otro dentro de otro dentro de otro dentro de otro….) las consultas que pudiésemos realizar nos traerían demasiada información innecesaria.

A lo que quiero llegar con esto es que mientras nuestro esquema de documentos embebidos se haga más grande, será más complicado obtener información determinada. Si conocemos muy bien la estructura y las consultas que realizamos son similares, esto no representaría un problema. Pero si nuestro objetivo es realizar consultas de manera aleatoria y que no sigan ningún patrón en específico (lo cual es más común), es mucho mejor recurrir a los documentos referenciados.

Como conclusión podemos decir que el diseño de un modelo de datos en mongo más que una ciencia, representa un arte. Ya vimos que existen 2 formas de hacer esto, analizamos sus ventajas y desventajas. Nadie nos va a decir cuál es la correcta o más adecuada pues al final la decisión que se pretenda implementar dependerá de la forma en que nuestra aplicación va a acceder a los datos.

So, what are you going to do?

To embed or reference? (8

Hasta la próxima.

 

Leave a Reply

Your email address will not be published. Required fields are marked *