Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/tutosrive/db-relacionales-2026-1/llms.txt

Use this file to discover all available pages before exploring further.

La normalización es el proceso sistemático de organizar los atributos y tablas de una base de datos relacional para minimizar la redundancia de datos y eliminar las anomalías de actualización, inserción y eliminación. Una base de datos no normalizada puede contener el mismo dato en múltiples lugares: si ese dato cambia, hay que actualizarlo en todos lados simultáneamente, y si alguna actualización falla, la base de datos queda en un estado inconsistente. La teoría de la normalización, desarrollada por Edgar F. Codd y posteriormente extendida por otros investigadores, ofrece un conjunto de reglas formales —las formas normales— que guían el diseño hacia esquemas más robustos, predecibles y fáciles de mantener.

Dependencias funcionales

Antes de aplicar cualquier forma normal es necesario entender el concepto central de la normalización: la dependencia funcional. Definición: Dado un esquema de relación R, se dice que el atributo B depende funcionalmente del atributo A (notación: A → B) si, para cada valor de A en R, existe exactamente un valor de B asociado. Ejemplos en el dominio del curso:
DependenciaLectura
cedula → nombre, apellidoLa cédula de un alumno determina unívocamente su nombre y apellido
codcurso → nombrecurso, num_horasEl código del curso determina su nombre y duración
codcurso → cedprofesorCada curso tiene asignado exactamente un profesor
{cedula_alumno, codcurso} → inscripciónLa inscripción depende de la combinación alumno-curso
La dependencia funcional es una restricción semántica del dominio del negocio, no algo que se infiere automáticamente de los datos actuales. Que en este momento dos alumnos tengan la misma dirección no significa que direccion → cedula; hay que entender las reglas del negocio.

El proceso de normalización

1

Partir de una tabla universal (relación universal)

El punto de partida es una única tabla que contiene todos los atributos del dominio. Esta tabla generalmente viola varias formas normales y sirve como entrada al proceso.Tabla inicial — inscripcion_completa (no normalizada):
cedulanombre_alumnoapellido_alumnocodcursonombrecursonum_horascedprofesornombre_profesornota_finaltelefonos_alumno
101AnaGómezC01SQL Avanzado40P01Martínez4.53001234, 3109876
101AnaGómezC02Modelado ER30P02Rodríguez3.83001234, 3109876
102LuisPérezC01SQL Avanzado40P01Martínez4.03205555
Anomalías visibles:
  • Actualización: si el profesor Martínez cambia de nombre, hay que actualizarlo en cada fila donde aparezca.
  • Inserción: no se puede registrar un curso sin tener al menos un alumno inscrito.
  • Eliminación: si Luis Pérez cancela C01, se pierde la información de que el profesor P01 imparte ese curso.
2

Aplicar la Primera Forma Normal (1FN)

Primera Forma Normal (1FN)

Una tabla está en 1FN si:
  1. Todos los atributos contienen valores atómicos (indivisibles).
  2. No existen grupos repetitivos ni listas de valores en una sola celda.
  3. Cada fila es única (existe una clave primaria).
Violación identificada: la columna telefonos_alumno contiene múltiples valores separados por comas → viola la atomicidad.Tabla que viola 1FN:
cedulanombre_alumnotelefonos_alumno
101Ana Gómez3001234, 3109876
102Luis Pérez3205555
Solución — separar los teléfonos en una tabla propia:
-- Tabla principal de alumnos (ahora atómica)
CREATE TABLE alumnos (
  cedula           VARCHAR(15)  NOT NULL,
  nombre           VARCHAR(50)  NOT NULL,
  apellido         VARCHAR(50)  NOT NULL,
  direccion        VARCHAR(100),
  sexo             VARCHAR(1),
  fecha_nacimiento DATE,
  CONSTRAINT pk_alumnos PRIMARY KEY (cedula)
);

-- Tabla separada para el atributo multivaluado 'telefono'
CREATE TABLE alumno_telefonos (
  cedula   VARCHAR(15) NOT NULL,
  telefono VARCHAR(15) NOT NULL,
  CONSTRAINT pk_alumno_telefonos PRIMARY KEY (cedula, telefono),
  CONSTRAINT fk_alumno_tel FOREIGN KEY (cedula)
    REFERENCES alumnos(cedula) ON DELETE CASCADE
);
Un error frecuente en 1FN es usar columnas del tipo telefono1, telefono2, telefono3 para evitar la tabla separada. Esto también viola 1FN (grupos repetitivos disfrazados) y además limita el número máximo de teléfonos de forma arbitraria.
3

Aplicar la Segunda Forma Normal (2FN)

Segunda Forma Normal (2FN)

Una tabla está en 2FN si:
  1. Está en 1FN.
  2. Todos los atributos no clave dependen de toda la clave primaria (no solo de una parte de ella).
La 2FN solo es relevante cuando la clave primaria es compuesta. Una dependencia parcial ocurre cuando un atributo depende solo de un subconjunto de la clave.Tabla que viola 2FN:Supongamos que consolidamos la inscripción en una sola tabla con PK compuesta {cedula_alumno, codcurso}:
cedula_alumnocodcursonombre_alumnonombrecursonum_horas
10000001101AnaBase de Datos I100.1
10000001102AnaProgramacion Web150
10000002101PedroBase de Datos I100.1
Dependencias parciales:
  • cedula_alumno → nombre_alumno (depende solo de cedula_alumno, no de la PK completa)
  • codcurso → nombrecurso, num_horas (depende solo de codcurso)
  • {cedula_alumno, codcurso} identifica correctamente cada inscripción
Solución — descomponer en tablas con dependencias completas:
-- Datos del alumno dependen solo de cedula
CREATE TABLE alumnos (
  cedula           VARCHAR(15) NOT NULL,
  nombre           VARCHAR(50) NOT NULL,
  apellido         VARCHAR(50) NOT NULL,
  direccion        VARCHAR(100),
  sexo             VARCHAR(1),
  fecha_nacimiento DATE,
  CONSTRAINT pk_alumnos PRIMARY KEY (cedula)
);

-- Datos del curso dependen solo de codcurso
CREATE TABLE cursos (
  codcurso     INTEGER      NOT NULL,
  nombrecurso  VARCHAR(50)  NOT NULL,
  num_horas    NUMERIC(5,2),
  max_alumnos  INTEGER,
  titulo       VARCHAR(80),
  fecha_inicio DATE,
  fecha_fin    DATE,
  CONSTRAINT pk_cursos PRIMARY KEY (codcurso)
);

-- La combinación alumno + curso identifica la inscripción
CREATE TABLE alumno_curso (
  cedula_alumno VARCHAR(15)  NOT NULL,
  codcurso      INTEGER      NOT NULL,
  CONSTRAINT pk_alumno_curso PRIMARY KEY (cedula_alumno, codcurso),
  CONSTRAINT fk_ac_alumno  FOREIGN KEY (cedula_alumno)
    REFERENCES alumnos(cedula),
  CONSTRAINT fk_ac_curso   FOREIGN KEY (codcurso)
    REFERENCES cursos(codcurso)
);
4

Aplicar la Tercera Forma Normal (3FN)

Tercera Forma Normal (3FN)

Una tabla está en 3FN si:
  1. Está en 2FN.
  2. No existen dependencias transitivas: ningún atributo no clave depende de otro atributo no clave.
Tabla que viola 3FN:
codcursonombrecursocedprofesornombre_profesortitulo_profesor
101Base de Datos I12345678JuanIngeniero de Sistemas
102Programacion Web23456789MariaLicenciada en Matematicas
103Redes de Datos12345678JuanIngeniero de Sistemas
Dependencia transitiva identificada:
codcurso → cedprofesor → nombre_profesor, titulo_profesor
nombre_profesor no depende directamente de codcurso (la PK), sino transitivamente a través de cedprofesor.Solución — extraer la información del profesor a su propia tabla:
-- Tabla de profesores: atributos propios del profesor
CREATE TABLE profesores (
  cedula       VARCHAR(15)    NOT NULL,
  nombre       VARCHAR(50)    NOT NULL,
  apellido     VARCHAR(50)    NOT NULL,
  direccion    VARCHAR(100),
  titulo       VARCHAR(80),
  cuota_hora   NUMERIC(10,2),
  edad         INTEGER,
  CONSTRAINT pk_profesores PRIMARY KEY (cedula)
);

-- Tabla de cursos: solo referencia al profesor mediante FK
CREATE TABLE cursos (
  codcurso     INTEGER      NOT NULL,
  nombrecurso  VARCHAR(50)  NOT NULL,
  cedprofesor  VARCHAR(15)  NOT NULL,
  max_alumnos  INTEGER,
  titulo       VARCHAR(80),
  fecha_inicio DATE,
  fecha_fin    DATE,
  num_horas    NUMERIC(5,2),
  CONSTRAINT pk_cursos PRIMARY KEY (codcurso),
  CONSTRAINT fk_curso_prof FOREIGN KEY (cedprofesor)
    REFERENCES profesores(cedula)
);
La regla informal de la 3FN es: “cada atributo no clave debe depender de la clave, solo de la clave y nada más que de la clave” (paráfrasis del juramento anglosajón, popularizada por William Kent).
5

Verificar BCNF (opcional pero recomendado)

Forma Normal de Boyce-Codd (BCNF)

La BCNF es una versión más estricta de la 3FN. Una tabla está en BCNF si, para toda dependencia funcional no trivial X → Y, X es una superclave de la relación.La diferencia con 3FN aparece en tablas con múltiples claves candidatas solapadas. En la práctica, la mayoría de los esquemas en 3FN ya están en BCNF; los casos que violan BCNF pero no 3FN son relativamente raros.Consulta la sección de preguntas frecuentes al final de esta página para un ejemplo detallado de cuándo 3FN ≠ BCNF.
Forzar BCNF en todos los casos puede llevar a pérdida de dependencias funcionales (algunas restricciones del negocio ya no pueden expresarse con claves foráneas y requieren triggers o constraints adicionales). Evalúa caso a caso si el rigor de BCNF justifica esa complejidad.

Esquema final normalizado (3FN)

El siguiente DDL representa el esquema del curso completamente normalizado hasta 3FN:
-- =============================================
-- Esquema universitario normalizado hasta 3FN
-- =============================================

CREATE TABLE IF NOT EXISTS profesores (
  cedula       VARCHAR(15)   NOT NULL,
  nombre       VARCHAR(50)   NOT NULL,
  apellido     VARCHAR(50)   NOT NULL,
  direccion    VARCHAR(100),
  titulo       VARCHAR(80),
  cuota_hora   NUMERIC(10,2),
  edad         INTEGER,
  CONSTRAINT pk_profesores PRIMARY KEY (cedula)
);

CREATE TABLE IF NOT EXISTS alumnos (
  cedula           VARCHAR(15)  NOT NULL,
  nombre           VARCHAR(50)  NOT NULL,
  apellido         VARCHAR(50)  NOT NULL,
  direccion        VARCHAR(100),
  sexo             VARCHAR(1),
  fecha_nacimiento DATE,
  CONSTRAINT pk_alumnos PRIMARY KEY (cedula)
);

CREATE TABLE IF NOT EXISTS cursos (
  codcurso     INTEGER      NOT NULL,
  nombrecurso  VARCHAR(50)  NOT NULL,
  cedprofesor  VARCHAR(15)  NOT NULL,
  max_alumnos  INTEGER,
  titulo       VARCHAR(80),
  fecha_inicio DATE,
  fecha_fin    DATE,
  num_horas    NUMERIC(5,2),
  CONSTRAINT pk_cursos         PRIMARY KEY (codcurso),
  CONSTRAINT fk_curso_profesor FOREIGN KEY (cedprofesor)
    REFERENCES profesores(cedula)
);

CREATE TABLE IF NOT EXISTS alumno_curso (
  cedula_alumno VARCHAR(15)  NOT NULL,
  codcurso      INTEGER      NOT NULL,
  CONSTRAINT pk_alumno_curso PRIMARY KEY (cedula_alumno, codcurso),
  CONSTRAINT fk_ac_alumno    FOREIGN KEY (cedula_alumno)
    REFERENCES alumnos(cedula),
  CONSTRAINT fk_ac_curso     FOREIGN KEY (codcurso)
    REFERENCES cursos(codcurso)
);

CREATE TABLE IF NOT EXISTS alumno_telefonos (
  cedula   VARCHAR(15) NOT NULL,
  telefono VARCHAR(15) NOT NULL,
  CONSTRAINT pk_alumno_telefonos PRIMARY KEY (cedula, telefono),
  CONSTRAINT fk_at_alumno        FOREIGN KEY (cedula)
    REFERENCES alumnos(cedula) ON DELETE CASCADE
);

Resumen de las formas normales

Forma NormalRequisito principalProblema que elimina
1FNValores atómicos, sin grupos repetitivosCeldas con múltiples valores, columnas repetidas
2FNSin dependencias parciales de la PKRedundancia en tablas con PK compuesta
3FNSin dependencias transitivasRedundancia por cadenas de dependencia
BCNFTodo determinante es superclaveAnomalías residuales con claves candidatas solapadas
El peligro de la sobre-normalización: llevar un esquema a 4FN o 5FN puede resultar en decenas de tablas con joins costosos para consultas simples. En sistemas OLAP (analítica) y data warehouses se utilizan intencionalmente esquemas desnormalizados (estrella, copo de nieve) para mejorar el rendimiento de lectura. La normalización es una guía de diseño, no un dogma absoluto.

Preguntas frecuentes sobre normalización

Imagina una tabla para asignar tutores a alumnos en cursos, donde:
  • Cada alumno en un curso tiene exactamente un tutor.
  • Cada tutor solo imparte un curso (pero un curso puede tener varios tutores).
TUTORIA(cedula_alumno, codcurso, cedula_tutor)
Claves candidatas:
  • {cedula_alumno, codcurso} — un alumno en un curso tiene un tutor.
  • {cedula_alumno, cedula_tutor} — un alumno con un tutor determina el curso.
Dependencia funcional:
cedula_tutor → codcurso
Esta dependencia no viola 3FN porque cedula_tutor forma parte de una clave candidata. Pero sí viola BCNF porque cedula_tutor por sí sola no es superclave de la relación.La solución BCNF descompone la tabla, pero puede impedir expresar directamente la restricción de que el alumno y el tutor deben pertenecer al mismo curso, lo que requeriría un trigger adicional. Por eso a veces se prefiere mantener 3FN en estos casos.
Sí, hay un trade-off. Más tablas significan más JOIN en las consultas, lo que puede ser más lento si las tablas son muy grandes y los índices no están bien definidos. Sin embargo:
  1. Los índices en las claves foráneas mitigan en gran medida este costo.
  2. Las bases de datos normalizadas son más rápidas en escritura (menos filas que actualizar por cambio).
  3. Para cargas de trabajo de lectura intensiva (reportería, BI), considera vistas materializadas o esquemas estrella en una capa separada de analítica.
La recomendación estándar es: diseña normalizado, desnormaliza solo donde los perfiles de rendimiento lo justifiquen con evidencia.
Sigue estos pasos:
  1. Entrevista al negocio: pregunta “¿puede haber dos registros con el mismo valor de X pero diferente valor de Y?”. Si la respuesta es no, tienes X → Y.
  2. Analiza las reglas de negocio documentadas, no solo los datos de muestra.
  3. Busca atributos descriptivos de otra entidad: si una tabla tiene nombre_ciudad junto a codigo_postal, sospecha de codigo_postal → nombre_ciudad.
  4. Usa el diagrama E-R como guía: los atributos de cada entidad deben depender funcionalmente de la clave de esa entidad.
  • 4FN elimina dependencias multivaluadas: cuando una tabla registra combinaciones independientes de dos atributos respecto a una clave (p. ej., un profesor puede enseñar varios cursos Y hablar varios idiomas, de forma independiente entre sí).
  • 5FN (forma normal de proyección-unión) maneja casos aún más raros de dependencias de join cíclicas.
En la práctica, la gran mayoría de los diseños empresariales se detienen en 3FN o BCNF. Las formas superiores son relevantes principalmente en contextos académicos o en esquemas muy específicos.

Build docs developers (and LLMs) love