Mongo DB
Mongo DB
Mongo DB
MongoDB desde Cero: Modelado de Datos
PUBLICADO POR: JONATHAN WIESEL (/AUTHOR/JONATHAN.HTML), EL 07/10/2013
Detalles del Curso: Twittear
Dificultad: Aprendiz 27
Duración: 15 min Like 100
Más artículos en MongoDB desde Cero (/series/mongodbdesdecero.html)
Este es el artículo Modelado de Datos de la serie MongoDB desde Cero Mostrar todos
Una de las dificultades que encuentran aquellos que se adentran al mundo del NoSQL es al tratar de transformar su esquema de base de datos relacional para que funcione
de la mejor manera segun el enfoque NoSQL orientado a documentos, como lo es MongoDB. Aquí aprenderemos sobre como realizar correctamente el modelado de datos
para que puedas comenzar a pensar en migrar tus proyectos a este tipo de base de datos con la menor dificultad posible.
Tipos de Datos
Al comienzo de la serie explicamos que los documentos de MongoDB son como objetos JSON, para ser especificos son de tipo BSON (JSON Binario), esta estrategia permite
la serialización de documentos tipo JSON codificados binariamente. Veamos algunos de los tipos de datos que soporta:
String Cadenas de caracteres.
Integer Números enteros.
Double Números con decimales.
Boolean Booleanos verdaderos o falsos.
Date Fechas.
Timestamp Estampillas de tiempo.
Null Valor nulo.
Array Arreglos de otros tipos de dato.
Object Otros documentos embebidos.
ObjectID Identificadores únicos creados por MongoDB al crear documentos sin especificar valores para el campo _id .
Data Binaria Punteros a archivos binarios.
Javascript código y funciones Javascript.
Patrones de Modelado
Existen 2 patrones principales que nos ayudarán a establecer la estructura que tendrán los documentos para lograr relacionar datos que en una base de datos relacional
estarían en diferentes tablas.
Embeber
Este patrón se enfoca en incrustar documentos uno dentro de otro con la finalidad de hacerlo parte del mismo registro y que la relación sea directa.
Si tienes experiencia en bases de datos orientadas o objetos, este patrón seguiría el mismo principio para la implementación de un TDA
(Tipo de Dato Abstracto).
Referenciar
Este patrón busca imitar el comportamiento de las claves foráneas para relacionar datos que deben estar en colecciones diferentes.
http://codehero.co/mongodbdesdeceromodeladodedatos/ 1/20
27/3/2017 MongoDB desde Cero Modelado de Datos CODEHERO
Debes tomar en cuenta cuando estés en el proceso de modelado que si piensas hacer muchas actualizaciones sobre datos de
colecciones relacionadas (en especial modificaciones atómicas), trata en lo posible de que aquellos datos que se vayan a modificar se
encuentren en el mismo documento.
Modelado de Relaciones
Bien, ha llegado el momento de aprender a transformar las relaciones de las tablas en las bases de datos relacionales. Empecemos con lo más básico.
Relaciones 11.
Muchas opiniones concuerdan que las relaciones 1 a 1 deben ser finalmente normalizadas para formar una única tabla; sin embargo existen consideraciones especiales
donde es mejor separar los datos en tablas diferentes. Supongamos el caso que tenemos una tabla persona y otra tabla documentos personales, donde una persona
tiene un solo juego de documentos personales y que un juego de documentos personales solo puede pertenecer a una persona.
Si traducimos esto tal cual a lo que sabemos hasta ahora de MongoDB sería algo así:
1 Persona = {
2 nombre : 'Jonathan',
3 apellido : 'Wiesel',
4 genero : 'M'
5 }
6
7 DocumentosPersonales = {
8 pasaporte : 'D123456V7',
9 licencia : '34567651‐2342',
10 seguro_social : 'V‐543523452'
11 }
Para los casos de relaciones 1a1 se utiliza el patrón de embeber un documento en otro, por lo que el documento final quedaría así:
1 Persona = {
2 nombre : 'Jonathan',
3 apellido : 'Wiesel',
4 genero : 'M',
5 documentos : {
6 pasaporte : 'D123456V7',
7 licencia : '34567651‐2342',
8 seguro_social : 'V‐543523452'
9 }
10 }
Relaciones 1*
Supongamos ahora el caso de una tabla persona y otra tabla dirección. Donde una persona puede poseer varias direcciones.
http://codehero.co/mongodbdesdeceromodeladodedatos/ 2/20
27/3/2017 MongoDB desde Cero Modelado de Datos CODEHERO
Por el momento no nos pondremos creativos al pensar que una dirección puede pertenecer a más de una persona.
Traduciendolo tal cual a MongoDB tendríamos algo así:
1 Persona = {
2 nombre : 'Jonathan',
3 apellido : 'Wiesel',
4 genero : 'M'
5 }
6
7 Direccion1 = {
8 pais : 'Venezuela',
9 estado : 'Distrito Capital'
10 ciudad : 'Caracas'
11 urbanizacion : 'La Florida',
12 avenida : ...,
13 edificio : ...,
14 piso : ...,
15 apartamento : ...
16 }
17
18 Direccion2 = {
19 pais : 'Estados Unidos',
20 estado : 'Florida'
21 ciudad : 'Miami'
22 urbanizacion : 'Aventura',
23 avenida : ...,
24 edificio : ...,
25 piso : ...,
26 apartamento : ...
27 }
Ahora para transformar la relación tenemos 2 opciones.
Podemos embeber las direcciones en el documento de la persona al establecer un arreglo de direcciones embebidas:
http://codehero.co/mongodbdesdeceromodeladodedatos/ 3/20
27/3/2017 MongoDB desde Cero Modelado de Datos CODEHERO
1 Persona = {
2 nombre : 'Jonathan',
3 apellido : 'Wiesel',
4 genero : 'M',
5 direcciones : [{
6 pais : 'Venezuela',
7 estado : 'Distrito capital'
8 ciudad : 'Caracas',
9 urbanizacion : 'La Florida',
10 avenida : ...,
11 edificio : ...,
12 piso : ...,
13 apartamento : ...
14 },{
15 pais : 'Estados Unidos',
16 estado : 'Florida'
17 ciudad : 'Miami'
18 urbanizacion : 'Aventura',
19 avenida : ...,
20 edificio : ...,
21 piso : ...,
22 apartamento : ...
23 }]
24 }
ó podemos dejarlo en documentos separados. Para esta segunda opción tenemos 2 enfoques.
Uno sería agregar un campo de referencia a dirección en persona:
1 Direccion1 = {
2 _id : 1,
3 pais : 'Venezuela',
4 estado : 'Distrito Capital',
5 ciudad : 'Caracas'
6 urbanizacion : 'La Florida',
7 avenida : ...,
8 edificio : ...,
9 piso : ...,
10 apartamento : ...
11 }
12
13 Direccion2 = {
14 _id : 2,
15 pais : 'Estados Unidos',
16 estado : 'Florida',
17 ciudad : 'Miami'
18 urbanizacion : 'Aventura',
19 avenida : ...,
20 edificio : ...,
21 piso : ...,
22 apartamento : ...
23 }
24
25 Persona = {
26 nombre : 'Jonathan',
27 apellido : 'Wiesel',
28 genero : 'M',
29 direcciones : [1,2]
30 }
y el otro sería agregar un campo de referencia a persona en dirección:
http://codehero.co/mongodbdesdeceromodeladodedatos/ 4/20
27/3/2017 MongoDB desde Cero Modelado de Datos CODEHERO
1 Direccion1 = {
2 _id : 1,
3 pais : 'Venezuela',
4 estado : 'Distrito Capital',
5 ciudad : 'Caracas'
6 urbanizacion : 'La Florida',
7 avenida : ...,
8 edificio : ...,
9 piso : ...,
10 apartamento : ...,
11 persona_id : 1
12 }
13
14 Direccion2 = {
15 _id : 2,
16 pais : 'Estados Unidos',
17 estado : 'Florida',
18 ciudad : 'Miami'
19 urbanizacion : 'Aventura',
20 avenida : ...,
21 edificio : ...,
22 piso : ...,
23 apartamento : ...,
24 persona_id : 1
25 }
26
27 Persona = {
28 _id : 1
29 nombre : 'Jonathan',
30 apellido : 'Wiesel',
31 genero : 'M'
32 }
En lo posible trata de utilizar la opción de embeber si los arreglos no variarán mucho ya que al realizar la búsqueda de la persona
obtienes de una vez las direcciones, mientras que al trabajar con referencias tu aplicación debe manejar una lógica múltiples
búsquedas para resolver las referencias, lo que sería el equivalente a los joins.
En caso de utilizar la segunda opción, ¿Cual de los 2 últimos enfoques utilizar?. En este caso debemos tomar en cuenta que tanto
puede crecer la lista de direcciones, en caso que la tendencia sea a crecer mucho, para evitar arreglos mutantes y en constante
crecimiento el segundo enfoque sería el más apropiado.
Relaciones **
Finalmente nos ponemos creativos a decir que, en efecto, varias personas pueden pertenecer a la misma dirección.
Al aplicar normalización quedaría algo así:
Para modelar este caso es muy similar al de relaciones uno a muchos con referencia por lo que colocaremos en ambos tipos de documento un arreglo de referencias al otro
tipo. Agreguemos una persona adicional para demostrar mejor el punto:
http://codehero.co/mongodbdesdeceromodeladodedatos/ 5/20
27/3/2017 MongoDB desde Cero Modelado de Datos CODEHERO
1 Direccion1 = {
2 _id : 1,
3 pais : 'Venezuela',
4 estado : 'Distrito Capital',
5 ciudad : 'Caracas'
6 urbanizacion : 'La Florida',
7 avenida : ...,
8 edificio : ...,
9 piso : ...,
10 apartamento : ...,
11 personas : [1000]
12 }
13
14 Direccion2 = {
15 _id : 2,
16 pais : 'Estados Unidos',
17 estado : 'Florida',
18 ciudad : 'Miami'
19 urbanizacion : 'Aventura',
20 avenida : ...,
21 edificio : ...,
22 piso : ...,
23 apartamento : ...,
24 personas : [1000,1001]
25 }
26
27 Persona1 = {
28 _id : 1000,
29 nombre : 'Jonathan',
30 apellido : 'Wiesel',
31 genero : 'M',
32 direcciones : [1,2]
33 }
34
35 Persona2 = {
36 _id : 1001,
37 nombre : 'Carlos',
38 apellido : 'Cerqueira',
39 genero : 'M',
40 direcciones : [2]
41 }
Seguro debes estar esperando el caso más complejo de todos, aquellas ocasiones donde la tabla intermedia tiene campos adicionales.
Tomando como base el ejemplo anterior, agregaremos el campo adicional usando el patrón para embeber de la siguiente manera:
http://codehero.co/mongodbdesdeceromodeladodedatos/ 6/20
27/3/2017 MongoDB desde Cero Modelado de Datos CODEHERO
1 Direccion1 = {
2 _id : 1,
3 pais : 'Venezuela',
4 estado : 'Distrito Capital',
5 ciudad : 'Caracas'
6 urbanizacion : 'La Florida',
7 avenida : ...,
8 edificio : ...,
9 piso : ...,
10 apartamento : ...,
11 personas : [1000]
12 }
13
14 Direccion2 = {
15 _id : 2,
16 pais : 'Estados Unidos',
17 estado : 'Florida',
18 ciudad : 'Miami'
19 urbanizacion : 'Aventura',
20 avenida : ...,
21 edificio : ...,
22 piso : ...,
23 apartamento : ...,
24 personas : [1000,1001]
25 }
26
27 Persona1 = {
28 _id : 1000,
29 nombre : 'Jonathan',
30 apellido : 'Wiesel',
31 genero : 'M',
32 direcciones : [{
33 direccion_id : 1,
34 viveAqui : true
35 },{
36 direccion_id : 2,
37 viveAqui : false
38 }]
39 }
40
41 Persona2 = {
42 _id : 1001,
43 nombre : 'Carlos',
44 apellido : 'Cerqueira',
45 genero : 'M',
46 direcciones : [{
47 direccion_id : 2,
48 viveAqui : true
49 }]
50 }
Conclusión
En este curso hemos aprendido a modelar los datos que conforman una base de datos de MongoDB, con este nuevo conocimiento ya podemos evaluar la estructura de una
base de datos relacional para determinar si en efecto podemos transformarla fácilmente a NoSQL orientado a documentos y lograr aprovechar sus numerosas ventajas y
flexibilidad.
http://codehero.co/mongodbdesdeceromodeladodedatos/ 7/20