8. Modelado de datos

MongoDB es schemaless, pero eso no significa que no debas pensar en tu modelo de datos.

Diferencias con SQL

En SQL, defines columnas a nivel de tabla. En MongoDB, defines campos a nivel de documento. Esto significa que cada documento puede tener campos diferentes.

// Esto es válido en MongoDB
db.users.insertMany([
    { name: 'Ana', age: 28 },
    { name: 'Carlos', age: 35, city: 'Madrid' },
    { name: 'Laura', email: 'laura@example.com' }
])

Referencias vs Documentos embebidos

Tienes dos formas principales de relacionar datos:

Referencias (similar a foreign keys)

// Colección employees
{
    _id: 698,
    name: 'Duncan',
    manager: 485  // Referencia al manager
}

// Para obtener el manager:
var employee = db.employees.findOne({ _id: 698 })
var manager = db.employees.findOne({ _id: employee.manager })

Documentos embebidos

{
    _id: 501,
    name: 'Ghanima',
    family: {
        mother: 'Chani',
        father: 'Paul',
        brother: 485
    }
}

// Buscar por campos embebidos usa notación de punto
db.employees.find({ 'family.mother': 'Chani' })

¿Cuándo usar cada uno?

Usa referencias cuando:

  • Los datos se usan en diferentes contextos
  • Los datos cambian frecuentemente
  • Necesitas evitar duplicación
  • Los documentos son muy grandes

Usa documentos embebidos cuando:

  • Los datos casi siempre se consultan juntos
  • Los datos no cambian mucho
  • Quieres mejor rendimiento (una sola consulta)
  • Los documentos son pequeños

Arrays de valores

MongoDB maneja arrays como ciudadanos de primera clase:

{
    name: 'Ana',
    hobbies: ['lectura', 'programación', 'música']
}

// Buscar usuarios que tienen un hobby específico
db.users.find({ hobbies: 'programación' })

Los arrays también pueden contener documentos:

{
    name: 'Ana',
    addresses: [
        { type: 'casa', city: 'Madrid', street: 'Gran Vía 1' },
        { type: 'trabajo', city: 'Madrid', street: 'Alcalá 42' }
    ]
}

// Buscar por campos dentro del array
db.users.find({ 'addresses.city': 'Madrid' })

Desnormalización

A diferencia de SQL donde evitas duplicar datos, en MongoDB a veces duplicar datos es la mejor opción:

// En lugar de solo el user_id
{
    post: 'Mi primer post',
    user_id: 123
}

// Puedes almacenar también el nombre
{
    post: 'Mi primer post',
    user: {
        id: 123,
        name: 'Ana'
    }
}

Ventajas:

  • Una sola consulta para obtener todo
  • Mejor rendimiento
  • Los datos se leen juntos

Desventajas:

  • Si Ana cambia su nombre, debes actualizar múltiples documentos
  • Más espacio de almacenamiento

Límite de tamaño

Cada documento tiene un límite de 16 MB. Si necesitas almacenar archivos grandes, usa GridFS.

Ejemplo práctico: blog

Para un blog, podrías modelar:

Opción 1: Comentarios en colección separada

// Posts
{ _id: 1, title: 'Mi post', content: '...' }

// Comments
{ post_id: 1, author: 'Ana', text: 'Gran post' }

Opción 2: Comentarios embebidos

{
    _id: 1,
    title: 'Mi post',
    content: '...',
    comments: [
        { author: 'Ana', text: 'Gran post' },
        { author: 'Carlos', text: 'Interesante' }
    ]
}

Opción 3: Híbrida (recomendada)

{
    _id: 1,
    title: 'Mi post',
    content: '...',
    // Primeros comentarios embebidos
    recent_comments: [
        { author: 'Ana', text: 'Gran post' },
        { author: 'Carlos', text: 'Interesante' }
    ],
    total_comments: 152
}

// El resto en colección separada

Esto te da rendimiento (primeros comentarios en una consulta) y escalabilidad (si hay muchos comentarios).

This work is under a Attribution-NonCommercial-NoDerivatives 4.0 International license.

Desafíos de programación atemporales y multiparadigmáticos

Desafíos de programación atemporales y multiparadigmáticos

Te encuentras ante un librillo de actividades, divididas en 2 niveles de dificultad. Te enfrentarás a los casos más comunes que te puedes encontrar en pruebas técnicas o aprender conceptos elementales de programación.

Buy the book

Will you buy me a coffee?

Comments

There are no comments yet.

Visitors in real time

You are alone: 🐱