README · by ansango
← Volver al libro

Data models: relacional vs documento

El debate clásico de los modelos de datos, el object-relational mismatch, la normalización y cuándo cada modelo gana

~4 min de lectura
Resumen

La elección del modelo de datos condiciona todo lo demás: cómo se expresa la aplicación, qué garantías ofrece la base de datos, cómo se escala. Kleppmann y Riccomini revisan los principales modelos: relacional, documental, grafo y triple stores. Esta nota cubre los dos primeros y la cuestión de la normalización.

Por qué el modelo importa

El libro arranca con una afirmación que parece obvia y rara vez se examina: el modelo de datos determina cómo pensamos sobre el problema. Un sistema modelado en tablas relacionales hace fácil unas preguntas y difíciles otras. Lo mismo ocurre con el modelo documental o el modelo de grafos.

“Cada capa de abstracción es una manera de restringir lo que puedes hacer.”

Un buen modelo de datos es el que encaja con el problema y permite evolucionar.

El modelo relacional

El modelo relacional, propuesto por Edgar Codd (1970) y encarnado en SQL, dominó la informática empresarial durante cuarenta años. Sus principios:

-- Tabla de clientes (modelo relacional)
CREATE TABLE customers (
    id         SERIAL PRIMARY KEY,
    name       VARCHAR(255) NOT NULL,
    email      VARCHAR(255) UNIQUE NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT NOW()
);

-- Tabla de pedidos
CREATE TABLE orders (
    id          SERIAL PRIMARY KEY,
    customer_id INTEGER NOT NULL REFERENCES customers(id),
    total       DECIMAL(10, 2) NOT NULL,
    created_at  TIMESTAMP NOT NULL DEFAULT NOW(),
    status      VARCHAR(50) NOT NULL
);

Ventajas del modelo relacional

Limitaciones

El modelo documental

El modelo documental (MongoDB, CouchDB, Couchbase, DynamoDB) almacena los datos como documentos auto-contenidos, típicamente en formato JSON.

// Un "cliente" en modelo documental
{
    "id": "user-123",
    "name": "Ana García",
    "email": "[email protected]",
    "created_at": "2024-01-15T10:30:00Z",
    "orders": [
        { "id": 1, "total": 99.99, "items": [...] },
        { "id": 2, "total": 149.50, "items": [...] }
    ],
    "preferences": {
        "language": "es",
        "notifications": true
    }
}

Ventajas del modelo documental

Limitaciones

MongoDB no es lo que era

MongoDB ha evolucionado mucho. Tiene transacciones multi-documento (desde 4.0), índices, agregaciones. La diferencia con relacional se ha estrechado. Pero la mentalidad sigue siendo distinta.

El object-relational mismatch

El libro describe con detalle el impedance mismatch: la dificultad de mapear objetos en aplicaciones a tablas relacionales.

# Un objeto en Python
class User:
    def __init__(self, id, name, email, orders=[], preferences={}):
        self.id = id
        self.name = name
        self.email = email
        self.orders = orders  # lista de Order
        self.preferences = preferences  # dict

# ¿Cómo guardar este objeto en SQL?
# Opción 1: una tabla con todos los campos aplanados
# Opción 2: varias tablas con JOINs
# Opción 3: JSON serializado en una columna

Las tres opciones

OpciónVentajasDesventajas
AplanarConsultas rápidasDatos duplicados, anomalías de actualización
JOINsNormalización, sin duplicaciónMás consultas, latencia mayor
JSON en columnaCercano al objeto, flexiblePierde capacidades SQL
No hay bala de plata

Cada opción tiene un trade-off. El libro insiste en que la decisión depende del patrón de consulta dominante de la aplicación.

Normalización

La normalización es el proceso de diseñar tablas para evitar anomalías (problemas al actualizar datos).

Las formas normales

Primera forma normal (1NF): cada columna contiene un valor atómico (no listas).

-- MAL: viola 1NF (lista en una columna)
CREATE TABLE orders (
    id INTEGER,
    product_ids VARCHAR(255)  -- "1,2,3,4"
);

-- BIEN: 1NF (una fila por producto)
CREATE TABLE orders (
    id INTEGER,
    product_id INTEGER
);

Segunda forma normal (2NF): 1NF + cada columna no-clave depende de la clave completa.

Tercera forma normal (3NF): 2NF + no hay dependencias transitivas.

Forma normal de Boyce-Codd (BCNF): 3NF con restricciones más estrictas.

Cuándo desnormalizar

El libro es claro: la normalización es la disciplina por defecto, pero hay casos donde desnormalizar tiene sentido:

El data warehouse es un desnormalizado por diseño

Star schema, snowflake schema, tablas anchas: todo eso es desnormalización controlada. El data warehouse no debe seguir las formas normales de OLTP.

SQL y la flexibilidad

El libro destaca que SQL, pese a su fama de rígido, es bastante flexible:

-- Postgres: columna JSON con índice
CREATE TABLE events (
    id SERIAL PRIMARY KEY,
    data JSONB NOT NULL,
    created_at TIMESTAMP NOT NULL
);

CREATE INDEX idx_events_data ON events USING GIN (data);

-- Consulta con JSON
SELECT * FROM events
WHERE data->>'type' = 'purchase'
  AND (data->>'amount')::numeric > 100;

Cuándo cada modelo

El libro resume con un cuadro equilibrado:

CasoModelo recomendado
Datos tabulares, transacciones, reporting estándarRelacional
Datos jerárquicos naturales, esquemas cambiantesDocumental
Datos muy conectados, muchos joinsGrafo (lo vemos en otra nota)
Datos estructurados con esquema estableRelacional
Prototipado rápido, esquema desconocidoDocumental
Datos analíticos con muchas agregacionesColumnar (warehouse)
Los lenguajes de modelo importan

El modelo de datos se expresa en un lenguaje. SQL es muy maduro. Los lenguajes de las bases documentales son variados (MongoDB Query Language, DynamoDB Query, etc.). La elección del lenguaje puede importar más que la del modelo.

Híbridos en la práctica

El libro insiste en una observación importante: pocas empresas modernas usan un solo modelo. Lo típico:

Sistema real típico:

┌─────────────────────────────────────────────┐
│            Aplicación                       │
└──────────┬──────────┬──────────┬─────────────┘
           │          │          │
           ▼          ▼          ▼
       ┌──────┐  ┌──────┐  ┌──────────┐
       │Postgres│ │Redis │  │MongoDB   │
       │OLTP   │  │cache │  │documentos │
       └──────┘  └──────┘  └──────────┘


       ┌──────────────┐
       │  BigQuery    │
       │  warehouse   │
       └──────────────┘
Polyglot persistence

El término técnico para usar múltiples bases de datos en el mismo sistema. Es la norma, no la excepción. La complejidad operativa es real; el libro advierte contra ella.

Resumen en tres frases

Próximos pasos