La Cuarta Forma Normal explicada paso a paso con ejemplos

D
DanisCh
(Actualizado: ) • 14 min de lectura
La Cuarta Forma Normal explicada paso a paso con ejemplos
Conceptos de Base de Datos

Con la Primera, Segunda y Tercera Forma Normal tienes un diseño libre de redundancias causadas por dependencias parciales y transitivas. La mayoría de las bases de datos de aplicaciones reales no necesitan ir más allá. Pero existe un tipo de redundancia más sutil que las tres primeras formas normales no detectan ni corrigen.

Imagina una tabla donde todos los atributos dependen directamente de la clave primaria, sin dependencias parciales ni transitivas. A simple vista parece perfecta. Sin embargo, si la tabla registra dos tipos de información independientes entre sí asociados a la misma entidad, los datos se multiplican de forma innecesaria y aparecen anomalías que no deberían existir.

Ese problema lo resuelve la Cuarta Forma Normal (4FN).

El concepto que necesitas entender: dependencia multivaluada

Para entender la 4FN necesitas entender qué es una dependencia multivaluada. Es un concepto nuevo, diferente a la dependencia funcional que conoces de las formas anteriores.

Una dependencia funcional dice: si conoces el valor de A, puedes determinar de forma única el valor de B. Es una relación de uno a uno: un ID de producto determina un solo nombre de producto.

Una dependencia multivaluada dice algo diferente: dado el valor de A, existe un conjunto de valores de B que le corresponden, y ese conjunto es completamente independiente del conjunto de valores de C. Lo escribimos así: A →→ B (A multidetermina B).

La clave está en la palabra independiente. Si un empleado puede tener varios idiomas y varias habilidades, y la lista de idiomas no tiene ninguna relación con la lista de habilidades (saber inglés no implica saber Python, ni viceversa), entonces tienes dos dependencias multivaluadas independientes:

  • empleado →→ idiomas
  • empleado →→ habilidades

Cuando estas dos dependencias multivaluadas independientes coexisten en la misma tabla, la tabla viola la 4FN.

Definición formal de la Cuarta Forma Normal

Una tabla está en Cuarta Forma Normal cuando cumple estas condiciones:

  • Ya está en Tercera Forma Normal (o en Forma Normal de Boyce-Codd, que es una versión más estricta de la 3FN).
  • Para toda dependencia multivaluada no trivial A →→ B, A es una superclave de la tabla.

Una dependencia multivaluada es trivial cuando B es un subconjunto de A, o cuando A unido con B contiene todas las columnas de la tabla. En esos casos no hay problema. El problema aparece cuando la dependencia multivaluada es no trivial y A no es superclave.

En términos prácticos: si una tabla registra dos (o más) conjuntos de valores independientes para la misma entidad, esa tabla viola la 4FN y debe dividirse.

El problema visualizado: por qué aparece redundancia

Antes de ver el ejemplo completo, entendamos intuitivamente por qué las dependencias multivaluadas independientes crean redundancia.

Supón que tienes un empleado que habla tres idiomas: Español, Inglés y Francés. Y ese mismo empleado tiene dos habilidades: Python y SQL.

Si intentas registrar toda esa información en una sola tabla con una fila por combinación, obtienes esto:

id_empleadoidiomahabilidad
E001EspañolPython
E001EspañolSQL
E001InglésPython
E001InglésSQL
E001FrancésPython
E001FrancésSQL

Tres idiomas multiplicados por dos habilidades dan seis filas. Pero la información real son solo cinco datos: tres idiomas y dos habilidades. La tabla tiene seis filas para representar cinco hechos. Eso es redundancia pura.

Ahora imagina que el empleado aprende un tercer lenguaje de programación: JavaScript. Tienes que agregar tres filas más, una por cada idioma que ya tenía. Si el empleado aprende un cuarto idioma: cuatro filas más. El número de filas crece con el producto de las dos listas en lugar de con su suma.

Primer ejemplo completo: empleados con idiomas y habilidades

Tabla empleado_competencias (viola la 4FN):

id_empleado (PK)idioma (PK)habilidad (PK)
E001EspañolPython
E001EspañolSQL
E001InglésPython
E001InglésSQL
E001FrancésPython
E001FrancésSQL
E002EspañolJava
E002EspañolDocker
E002InglésJava
E002InglésDocker

Las dos dependencias multivaluadas son independientes entre sí:

id_empleado →→ idioma      (un empleado habla varios idiomas)
id_empleado →→ habilidad   (un empleado tiene varias habilidades)

Saber qué idiomas habla E001 no te dice nada sobre sus habilidades, y viceversa. Son dos hechos completamente independientes que no deberían estar en la misma tabla.

Los problemas que esto causa

  • Anomalía de inserción: si E001 aprende JavaScript, debes insertar tres filas nuevas (una por cada idioma que ya tiene). Si olvidas una, la base de datos queda en un estado inconsistente: el empleado aparece con JavaScript en unos idiomas pero no en otros.
  • Anomalía de eliminación: si quieres eliminar que E001 sabe Francés, tienes que eliminar dos filas (una por Python y otra por SQL). Si borras solo una, queda un registro inconsistente.
  • Anomalía de actualización: cualquier cambio en los idiomas o habilidades requiere tocar varias filas de forma coordinada.
  • Datos falsos implícitos: la tabla parece decir que existe una relación entre hablar Español y saber Python, cuando en realidad son hechos independientes.

Solución: una tabla por cada dependencia multivaluada

La 4FN se aplica separando cada dependencia multivaluada independiente en su propia tabla.

Tabla empleado_idiomas:

id_empleado (PK)idioma (PK)
E001Español
E001Inglés
E001Francés
E002Español
E002Inglés

Tabla empleado_habilidades:

id_empleado (PK)habilidad (PK)
E001Python
E001SQL
E002Java
E002Docker

Ahora la información de E001 ocupa 5 filas en total (3 + 2) en lugar de 6. Y si aprende JavaScript, solo agrega 1 fila en empleado_habilidades. Si aprende un nuevo idioma, solo agrega 1 fila en empleado_idiomas. Los hechos independientes viven separados.

-- Consultar todos los idiomas y habilidades de un empleado
SELECT
  e.nombre,
  ei.idioma,
  eh.habilidad
FROM empleados e
LEFT JOIN empleado_idiomas    ei ON ei.id_empleado = e.id
LEFT JOIN empleado_habilidades eh ON eh.id_empleado = e.id
WHERE e.id = 'E001';

-- Buscar todos los empleados que hablan Inglés y saben Python
SELECT DISTINCT e.nombre
FROM empleados e
JOIN empleado_idiomas    ei ON ei.id_empleado = e.id AND ei.idioma    = 'Inglés'
JOIN empleado_habilidades eh ON eh.id_empleado = e.id AND eh.habilidad = 'Python';

Segundo ejemplo: cursos con profesores y libros de texto

Un caso universitario. Un curso puede ser impartido por varios profesores y puede usar varios libros de texto. Los profesores y los libros son independientes entre sí: el hecho de que un curso use un libro no está relacionado con qué profesor lo imparte.

Tabla curso_recursos (viola la 4FN):

id_curso (PK)profesor (PK)libro (PK)
C01Prof. GarcíaClean Code
C01Prof. GarcíaThe Pragmatic Programmer
C01Prof. LópezClean Code
C01Prof. LópezThe Pragmatic Programmer
C02Prof. RuizDesign Patterns
C02Prof. RuizRefactoring
C02Prof. MoraDesign Patterns
C02Prof. MoraRefactoring

Las dependencias multivaluadas independientes:

id_curso →→ profesor   (un curso tiene varios profesores)
id_curso →→ libro      (un curso usa varios libros)

El curso C01 tiene 2 profesores y 2 libros, lo que genera 4 filas. Si añaden un tercer profesor, hay que insertar 2 filas más (una por cada libro). Si añaden un tercer libro, otras 2 filas más. Las anomalías son exactamente las mismas que en el ejemplo anterior.

Solución

Tabla curso_profesores:

id_curso (PK)profesor (PK)
C01Prof. García
C01Prof. López
C02Prof. Ruiz
C02Prof. Mora

Tabla curso_libros:

id_curso (PK)libro (PK)
C01Clean Code
C01The Pragmatic Programmer
C02Design Patterns
C02Refactoring

C01 pasa de 4 filas a 2 + 2 = 4 filas en total, pero distribuidas en dos tablas. Si se añade un tercer profesor al curso C01, solo se inserta 1 fila en curso_profesores, no 2. Si se añade un tercer libro, solo 1 fila en curso_libros, no 2.

Tercer ejemplo: productos con colores y tallas

Un ejemplo del mundo del comercio electrónico. Una camiseta puede venderse en varios colores y en varias tallas. Los colores y las tallas son independientes: que exista la talla M no implica nada sobre si existe el color rojo, y viceversa.

Tabla producto_variantes (viola la 4FN):

id_producto (PK)color (PK)talla (PK)
CAM001RojoS
CAM001RojoM
CAM001RojoL
CAM001AzulS
CAM001AzulM
CAM001AzulL
CAM001VerdeS
CAM001VerdeM
CAM001VerdeL

Tres colores por tres tallas dan nueve filas para representar seis hechos independientes. Si añaden el color Negro, necesitan tres filas más. Si añaden la talla XL, necesitan tres filas más.

Dependencias multivaluadas:

id_producto →→ color   (un producto tiene varios colores)
id_producto →→ talla   (un producto tiene varias tallas)

Solución

Tabla producto_colores:

id_producto (PK)color (PK)
CAM001Rojo
CAM001Azul
CAM001Verde

Tabla producto_tallas:

id_producto (PK)talla (PK)
CAM001S
CAM001M
CAM001L

Nueve filas se convierten en seis. Añadir el color Negro: 1 fila. Añadir la talla XL: 1 fila. Sin anomalías.

Pero aquí hay un matiz importante: en comercio electrónico, a veces sí existe una relación entre color y talla. Por ejemplo, si la camiseta verde solo está disponible en talla L, o si una combinación específica tiene stock diferente. En ese caso, la combinación (id_producto, color, talla) sí representa un hecho propio con atributos adicionales como el stock, y entonces la tabla original tendría sentido porque los tres campos juntos forman la clave de una entidad con significado real.

-- Si color y talla juntos tienen atributos propios (como stock),
-- la tabla tiene sentido como entidad propia:
CREATE TABLE producto_variantes (
  id_producto  VARCHAR(10) NOT NULL,
  color        VARCHAR(50) NOT NULL,
  talla        VARCHAR(5)  NOT NULL,
  stock        INT         DEFAULT 0,   -- atributo de la combinación
  sku          VARCHAR(20) UNIQUE,      -- atributo de la combinación
  PRIMARY KEY (id_producto, color, talla)
);
-- En este caso NO viola 4FN porque la combinación tiene significado propio

La 4FN se viola cuando los conjuntos son verdaderamente independientes y no existe ningún atributo que pertenezca específicamente a la combinación.

Cuarto ejemplo: pizzas con ingredientes y zonas de reparto

Un ejemplo que muestra con claridad cuándo dos conjuntos son independientes:

Tabla pizza_info (viola la 4FN):

pizza (PK)ingrediente (PK)zona_reparto (PK)
MargaritaTomateCentro
MargaritaTomateNorte
MargaritaMozzarellaCentro
MargaritaMozzarellaNorte
MargaritaAlbahacaCentro
MargaritaAlbahacaNorte

¿Tiene la Mozzarella alguna relación con que se reparte en el Norte? Ninguna. Son dos hechos completamente independientes sobre la pizza Margarita. Tres ingredientes por dos zonas: seis filas para representar cinco hechos.

pizza →→ ingrediente    (una pizza tiene varios ingredientes)
pizza →→ zona_reparto   (una pizza se reparte en varias zonas)

Solución

Tabla pizza_ingredientes:

pizza (PK)ingrediente (PK)
MargaritaTomate
MargaritaMozzarella
MargaritaAlbahaca

Tabla pizza_zonas:

pizza (PK)zona_reparto (PK)
MargaritaCentro
MargaritaNorte

Cómo distinguir una dependencia multivaluada de una funcional

La diferencia entre dependencia funcional y dependencia multivaluada es importante y a veces confusa. Aquí está la clave:

AspectoDependencia funcionalDependencia multivaluada
NotaciónA → BA →→ B
Cuántos valores de BExactamente unoUn conjunto de valores
Ejemploid_producto → nombre (un producto tiene un solo nombre)id_empleado →→ idioma (un empleado habla varios idiomas)
Viola 3FN cuandoA no es clave y A → B → CNo aplica a 3FN
Viola 4FN cuandoNo aplica a 4FN directamenteHay dos o más MVD independientes en la misma tabla

La pregunta clave para detectar violaciones de la 4FN

Cuando tienes una tabla con tres o más columnas en la clave primaria y no hay atributos adicionales fuera de la clave, hazte esta pregunta:

¿Si quito temporalmente la tercera columna de la clave, las otras dos siguen teniendo significado independiente respecto a la entidad principal?

En la tabla (empleado, idioma, habilidad):

  • ¿Tiene sentido la relación empleado-idioma por sí sola? Sí: el empleado habla esos idiomas independientemente de sus habilidades.
  • ¿Tiene sentido la relación empleado-habilidad por sí sola? Sí: el empleado tiene esas habilidades independientemente de los idiomas.
  • ¿La combinación idioma-habilidad tiene algún significado especial para ese empleado? No.

Respuesta: las dos relaciones son independientes. La tabla viola la 4FN.

Contraste con la tabla (pedido, producto, cantidad):

  • ¿Tiene sentido la relación pedido-producto por sí sola sin la cantidad? No del todo: lo que importa es cuántas unidades de ese producto están en ese pedido.
  • La combinación (pedido, producto) determina una cantidad específica. Hay un atributo (cantidad) que pertenece a la combinación.

Respuesta: no son independientes. La tabla no viola la 4FN.

Cuándo aparece la 4FN en la práctica

La 4FN aparece en situaciones donde una entidad tiene dos o más listas de valores sin relación entre sí. Los patrones más comunes son:

  • Una persona o entidad tiene varias categorías y varios roles al mismo tiempo.
  • Un producto tiene varios atributos de tipo A (colores, tallas, materiales) y varios atributos de tipo B que son independientes.
  • Un curso o programa tiene varios instructores y varios recursos (libros, materiales) no relacionados entre sí.
  • Una ubicación opera en varios idiomas y ofrece varios servicios independientes.

La 4FN en SQL: estructura correcta

-- Ejemplo completo: sistema de cursos en 4FN

-- Entidades principales
CREATE TABLE cursos (
  id     INT          AUTO_INCREMENT PRIMARY KEY,
  nombre VARCHAR(100) NOT NULL,
  nivel  VARCHAR(20)
);

CREATE TABLE profesores (
  id     INT          AUTO_INCREMENT PRIMARY KEY,
  nombre VARCHAR(100) NOT NULL,
  email  VARCHAR(100) UNIQUE
);

CREATE TABLE libros (
  id     INT          AUTO_INCREMENT PRIMARY KEY,
  titulo VARCHAR(200) NOT NULL,
  isbn   CHAR(13)     UNIQUE
);

-- Relaciones independientes: cada una en su propia tabla
-- Estas tablas existen porque curso →→ profesor y curso →→ libro son independientes

CREATE TABLE curso_profesores (
  id_curso   INT NOT NULL,
  id_profesor INT NOT NULL,
  PRIMARY KEY (id_curso, id_profesor),
  FOREIGN KEY (id_curso)    REFERENCES cursos(id),
  FOREIGN KEY (id_profesor) REFERENCES profesores(id)
);

CREATE TABLE curso_libros (
  id_curso INT NOT NULL,
  id_libro INT NOT NULL,
  PRIMARY KEY (id_curso, id_libro),
  FOREIGN KEY (id_curso) REFERENCES cursos(id),
  FOREIGN KEY (id_libro) REFERENCES libros(id)
);
-- Consultar todos los profesores y libros de cada curso
-- (el JOIN produce el producto cartesiano, que es lo que se quiere mostrar)
SELECT
  c.nombre          AS curso,
  p.nombre          AS profesor,
  l.titulo          AS libro
FROM cursos c
LEFT JOIN curso_profesores cp ON cp.id_curso = c.id
LEFT JOIN profesores p        ON p.id        = cp.id_profesor
LEFT JOIN curso_libros cl     ON cl.id_curso = c.id
LEFT JOIN libros l            ON l.id        = cl.id_libro
ORDER BY c.nombre, p.nombre, l.titulo;

Diferencias entre la 3FN y la 4FN

AspectoTercera Forma NormalCuarta Forma Normal
Qué eliminaDependencias transitivas entre atributos no claveDependencias multivaluadas independientes en la misma tabla
Tipo de dependenciaFuncional transitiva: A → B → CMultivaluada: A →→ B y A →→ C (independientes)
Frecuencia en la prácticaMuy comúnMenos frecuente, pero aparece en modelos complejos
La solución implicaExtraer la entidad intermedia a su propia tablaSeparar cada conjunto independiente en su propia tabla binaria
Señal de alertaUn atributo no clave que determina otro atributo no claveUna tabla sin atributos no clave cuya clave tiene tres o más columnas

¿Cuándo necesitas aplicar la 4FN en proyectos reales?

La mayoría de los sistemas de software de uso cotidiano no necesitan llegar a la 4FN. La 3FN es suficiente para casi todos los casos. La 4FN se vuelve relevante cuando:

  • Tu modelo de datos tiene entidades con múltiples atributos multivaluados independientes (etiquetas, categorías, capacidades, certificaciones, idiomas, zonas).
  • Notas que tus tablas de unión crecen de forma cuadrática en lugar de lineal cuando agregan nuevos valores.
  • Tienes anomalías de inserción y eliminación en tablas que parecen estar correctamente en 3FN.
  • Las tablas de relación tienen tres o más columnas en la clave y ningún atributo adicional fuera de ella.

Lista de verificación para la 4FN

  • ¿La tabla ya está en 3FN?
  • ¿La tabla tiene tres o más columnas formando la clave primaria sin atributos adicionales?
  • ¿Puedo dividir esa clave en dos pares (entidad, valor) que tengan sentido de forma completamente independiente?
  • ¿Cuando agrego un nuevo valor de tipo A tengo que insertar múltiples filas (una por cada valor de tipo B existente)?
  • ¿Cuando elimino todos los valores de tipo A queda algún valor de tipo B huérfano o inconsistente?

Si las últimas tres respuestas son sí, la tabla viola la 4FN y necesita dividirse.

Conclusión

La Cuarta Forma Normal aborda un tipo de redundancia que las tres formas normales anteriores no alcanzan a detectar: la coexistencia de dos conjuntos de valores completamente independientes en la misma tabla, lo que genera un crecimiento cuadrático de filas y anomalías al insertar, actualizar o eliminar datos.

La solución siempre es la misma: identificar las dependencias multivaluadas independientes y darle a cada una su propia tabla binaria. El resultado es un diseño donde cada tabla registra exactamente un tipo de relación, sin mezclar hechos que no tienen ninguna conexión entre sí.

Recuerda la progresión completa: la 1FN elimina los valores múltiples en celdas, la 2FN elimina las dependencias parciales, la 3FN elimina las dependencias transitivas, y la 4FN elimina las dependencias multivaluadas independientes. Cada forma normal construye sobre la anterior y deja la base de datos un poco más precisa, limpia y libre de anomalías.

Etiquetas: normalizacion

¿Te ha gustado esta entrada?

Compártela con tus compañeros para que también sigan aprendiendo.

Comunidad y Comentarios

0 COMENTARIOS

No hay comentarios todavía. Sé el primero en compartir tu opinión.

Escribe tu opinión
Respondiendo a