¿Te resulta más fácil leer con fondo crema, un tono de color, más contraste o un texto más grande? Elige tus colores y tu texto una sola vez, para todas las páginas.

Lección gratuita

Cada dato en un solo sitio

Después de esta lección: Puedo separar los datos en tablas para que cada dato se guarde una sola vez.

Lección de 45 minSin comandos

Dos teléfonos para un mismo cliente

Un taller de bicicletas de Bilbao guarda todas sus reparaciones en una sola tabla. Cada fila repite el nombre y el teléfono del cliente.

Un día, Iñaki cambia de número. Alguien lo actualiza en una fila, pero no en las otras.

Ahora el taller tiene dos teléfonos para Iñaki y no sabe a cuál llamar.

Al final de esta lección

Nota

Puedo separar los datos en tablas para que cada dato se guarde una sola vez.

Palabras clave

PalabraQué significa
Redundanciael mismo dato guardado en varios sitios
Inconsistenciados copias de un dato que no coinciden
Normalizarseparar los datos en tablas para no repetirlos
Desnormalizarrepetir un dato a propósito para leer más rápido
NoSQLbases de datos que no guardan tablas, sino documentos u otras formas

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Repetir un dato acaba en contradicción

Si un dato está escrito en tres filas, hay que cambiarlo en las tres. Basta con olvidar una para que la tabla diga dos cosas distintas.

Ese problema se llama inconsistencia. Pasa con teléfonos, direcciones y precios, y siempre sale caro: una llamada al número equivocado, un paquete perdido.

Prueba: encuentra la contradicción

Código: sql
-- ¿Cuántos teléfonos distintos tiene Iñaki?
SELECT customer, phone, COUNT(*) AS num_rows
FROM repairs
GROUP BY customer, phone;

-- Un mismo cliente con dos teléfonos: ¿cuál es el bueno?

Cada cosa en su propia tabla

La solución es separar. Los clientes van en una tabla customers, con su teléfono una sola vez.

Las reparaciones van en otra tabla y solo guardan customer_id, una clave foránea.

Para saber de quién es una reparación, unes las dos tablas con JOIN. Si Iñaki cambia de número, cambias una sola fila.

Prueba: un cambio en un solo sitio

Código: sql
-- Iñaki cambia de teléfono: se cambia en un solo sitio.
UPDATE customers SET phone = '622999888' WHERE id = 1;

-- Todas sus reparaciones muestran ya el número nuevo.
SELECT repairs.id, customers.name, customers.phone, repairs.price
FROM repairs
JOIN customers ON repairs.customer_id = customers.id;

Ejemplo: antes y después de separar

Una tablaDos tablas
Teléfono de IñakiEscrito 3 vecesEscrito 1 vez
Cambiar su número3 filas1 fila
Ver una reparación con su clienteUna consulta simpleUna consulta con JOIN
Riesgo de contradicciónAltoCasi nulo

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Un error frecuente

Advertencia

Mucha gente cree que hay que separar siempre al máximo. No siempre compensa. Un informe que se lee miles de veces al día puede guardar un total ya calculado. Es desnormalizar a propósito: se gana velocidad y se acepta cuidar esa copia.

Cuándo encaja una base NoSQL

Algunos datos no caben bien en columnas fijas. En una tienda, un casco tiene tallas y una luz tiene horas de batería.

Una base de documentos, como MongoDB, guarda cada ficha entera, con sus propios datos. Encaja cuando la ficha se lee de una vez y cambia de forma de un producto a otro. Para pedidos, pagos y clientes, las tablas siguen siendo la opción habitual.

Prueba: una ficha como documento

Código: python
# Una ficha de producto como documento, al estilo de una base NoSQL.
# Cada producto lleva los datos que necesita, sin columnas vacías.
helmet = {
    "name": "Casco urbano",
    "price": 49,
    "sizes": ["S", "M", "L"],
}
light = {
    "name": "Luz delantera",
    "price": 22,
    "battery_hours": 12,
}

for product in [helmet, light]:
    print(product["name"], "tiene", len(product), "datos")

# Añade a light el dato "color": "negro" y vuelve a ejecutar.

¿Enseñas a una clase? Asigna este módulo a tus alumnos con guía del profesor, tareas con corrección automática y un laboratorio para cada alumno.