Inicio > Cursos > SQL y Bases de Datos > Normalización de Base de Datos
SQL y Bases de DatosDiseño y OptimizaciónLección 11 de 20

Normalización de Base de Datos

La normalización es el proceso de diseñar tablas para eliminar redundancia. Sin normalización, los mismos datos aparecen en múltiples lugares: si un cliente cambia su dirección, habría que actualizarla en decenas de filas. Con normalización, cada dato existe en un solo lugar y se referencia desde otros.

Las tres formas normales básicas: 1FN (cada celda tiene un solo valor atómico, sin listas), 2FN (cada columna depende de toda la clave primaria, no solo parte de ella), 3FN (las columnas no dependen entre sí, solo de la clave primaria). En la práctica, llegar a 3FN es suficiente para la mayoría de los sistemas.

-- PROBLEMA: tabla de ventas sin normalizar
-- ventas_mal: id, cliente, email_cliente, telefono_cliente,
--   producto1, precio1, producto2, precio2, ciudad_cliente

-- 1FN: Primera Forma Normal
-- REGLA: sin grupos repetidos, cada celda un solo valor
-- Problema: producto1, producto2 son grupos repetidos
-- Solución: tabla separada para los items

-- 2FN: Segunda Forma Normal (requiere 1FN)
-- REGLA: cada columna depende de la PK completa
-- Solo aplica a tablas con PK compuesta
-- Problema: si PK es (venta_id, producto_id),
-- el nombre del producto depende solo de producto_id
-- Solución: separar productos en su propia tabla

-- 3FN: Tercera Forma Normal (requiere 2FN)
-- REGLA: sin dependencias transitivas
-- Problema: ciudad → codigo_postal → region
-- el region depende de codigo_postal, no del cliente directamente
-- Solución: tabla de codigos_postales separada

-- Diseño NORMALIZADO (3FN) del ejemplo de ventas:
CREATE TABLE clientes (
  id          SERIAL PRIMARY KEY,
  nombre      VARCHAR(100) NOT NULL,
  email       VARCHAR(255) UNIQUE NOT NULL,
  telefono    VARCHAR(20)
);

CREATE TABLE productos (
  id          SERIAL PRIMARY KEY,
  nombre      VARCHAR(200) NOT NULL,
  precio      DECIMAL(10, 2) NOT NULL,
  categoria   VARCHAR(100)
);

CREATE TABLE ventas (
  id          SERIAL PRIMARY KEY,
  cliente_id  INTEGER NOT NULL REFERENCES clientes(id),
  fecha       TIMESTAMP DEFAULT NOW()
);

CREATE TABLE venta_items (
  id          SERIAL PRIMARY KEY,
  venta_id    INTEGER NOT NULL REFERENCES ventas(id),
  producto_id INTEGER NOT NULL REFERENCES productos(id),
  cantidad    INTEGER NOT NULL CHECK (cantidad > 0),
  precio_venta DECIMAL(10, 2) NOT NULL  -- precio al momento de vender
);
-- Ventaja: si el precio del producto cambia, las ventas antiguas conservan
-- el precio correcto gracias a precio_venta.
ConsejoDesnormalizar es a veces válido para mejorar el rendimiento de lectura (caches, reportes). Por ejemplo, guardar el total de un pedido aunque se pueda calcular desde sus items evita recalcular en cada consulta. Normaliza primero, desnormaliza cuando los benchmarks lo justifiquen.
← Window FunctionsÍndices y Rendimiento →

Practica esta lección

Resuelve los ejercicios del curso de SQL y Bases de Datos en la app, gratis y con corrección automática.

Empezar a practicar