Relaciones · integridad referencial

ON UPDATE CASCADE con FOREIGN KEY

Entiende cuándo un cambio en una clave referenciada debe propagarse a las filas hijas y por qué las claves estables suelen reducir la necesidad de esta acción.

Lectura: 10–12 minEjemplo comprobadoPráctica con pistas
Contenido de esta guía

Respuesta rápida

ON UPDATE CASCADE hace que, cuando cambia el valor de una clave referenciada en la tabla padre, la base actualice automáticamente las claves foráneas correspondientes de las filas hijas.

Patrón
CREATE TABLE productos (
  id INTEGER PRIMARY KEY,
  categoria_codigo TEXT NOT NULL,
  FOREIGN KEY (categoria_codigo)
    REFERENCES categorias(codigo)
    ON UPDATE CASCADE
);

La acción solo se dispara si cambia la columna referenciada. No actualiza cualquier dato del padre y no significa que las claves deban modificarse con frecuencia.

Qué se propaga y en qué dirección

En una relación con clave foránea hay una tabla referenciada —el padre— y una tabla que guarda la referencia —el hijo—. Si productos.categoria_codigo apunta a categorias.codigo, cambiar el código del padre puede dejar referencias antiguas en los productos. Con ON UPDATE CASCADE, el motor copia el nuevo valor a las filas hijas relacionadas.

Efecto de ON UPDATE CASCADE
Cambio¿Activa la cascada?Resultado
categorias.codigo: ELEC → TECSíLos hijos que guardaban ELEC pasan a TEC
categorias.nombre: Electrónica → TecnologíaNoLa clave referenciada no cambió
Actualizar una fila de productosNoLa dirección es padre → hijo
Idea clave: ON UPDATE CASCADE protege la integridad cuando cambia la clave referenciada; no es un mecanismo general para sincronizar columnas entre tablas.

Ejemplo completo y comprobado

El siguiente ejemplo usa códigos legibles para que el efecto sea visible. En SQLite se activa explícitamente la comprobación de claves foráneas antes de crear las tablas.

SQL comprobado en SQLite
PRAGMA foreign_keys = ON;

CREATE TABLE categorias_update (
  codigo TEXT PRIMARY KEY,
  nombre TEXT NOT NULL
);

CREATE TABLE productos_update (
  id INTEGER PRIMARY KEY,
  nombre TEXT NOT NULL,
  categoria_codigo TEXT NOT NULL,
  FOREIGN KEY (categoria_codigo)
    REFERENCES categorias_update(codigo)
    ON UPDATE CASCADE
);

INSERT INTO categorias_update VALUES
  ('ELEC', 'Electrónica'),
  ('HOG', 'Hogar');

INSERT INTO productos_update VALUES
  (1, 'Monitor', 'ELEC'),
  (2, 'Teclado', 'ELEC'),
  (3, 'Lámpara', 'HOG');

UPDATE categorias_update
SET codigo = 'TEC'
WHERE codigo = 'ELEC';

SELECT id, nombre, categoria_codigo
FROM productos_update
ORDER BY id;
Productos después de cambiar ELEC por TEC
idnombrecategoria_codigo
1MonitorTEC
2TecladoTEC
3LámparaHOG

Solo las dos filas que referenciaban ELEC cambian a TEC. La lámpara conserva HOG porque su relación no depende de la clave actualizada.

Cuándo tiene sentido usar ON UPDATE CASCADE

La acción es especialmente útil cuando la clave referenciada puede cambiar legítimamente y ese cambio debe conservar la misma identidad lógica. Un código de negocio corregible —por ejemplo, un código de categoría— puede ser un caso razonable si muchas filas lo referencian.

Decisión práctica
SituaciónEnfoque habitualMotivo
Clave natural que puede corregirseEvaluar ON UPDATE CASCADEEvita dejar referencias con el valor anterior
ID técnico estableNormalmente no cambiarloUna clave sustituta suele diseñarse para conservar identidad
El cambio representa otra entidadNo usar cascada para «renombrarla»Puede corresponder crear una nueva fila y reasignar relaciones de forma explícita

No añadas la cascada solo porque un UPDATE del padre falla. Ese error puede estar avisando de que estás intentando cambiar una identidad que el modelo considera estable.

Por qué una PRIMARY KEY estable reduce este problema

Muchas bases usan un identificador técnico —por ejemplo, categoria_id— como PRIMARY KEY y guardan el código visible en otra columna. Así el código puede cambiar sin modificar la clave que usan las relaciones.

Clave técnica estable
CREATE TABLE categorias (
  id INTEGER PRIMARY KEY,
  codigo TEXT UNIQUE NOT NULL,
  nombre TEXT NOT NULL
);

-- Cambiar el código no altera la identidad referenciada por id.
UPDATE categorias
SET codigo = 'TEC'
WHERE id = 10;

Esto no convierte las claves sustitutas en una obligación universal. La decisión depende del dominio. Lo importante es distinguir entre identidad y atributos que pueden cambiar.

ON UPDATE CASCADE frente a otras acciones

Las claves foráneas pueden definir qué ocurre ante un cambio de la clave padre. Las opciones concretas varían por motor, pero las más comunes expresan decisiones distintas.

Acciones referenciales de actualización
AcciónIdea
CASCADECopia el nuevo valor del padre a las referencias hijas
NO ACTION / RESTRICTRechaza el cambio si dejaría referencias inválidas; el momento exacto de comprobación puede variar
SET NULLDeja la referencia en NULL si la columna lo permite
SET DEFAULTUsa el valor predeterminado cuando el motor y la restricción lo admiten

No todas las combinaciones están disponibles de la misma forma en todos los motores. Además, un valor producido por SET NULL o SET DEFAULT todavía debe respetar el resto de restricciones.

Errores frecuentes

Esperar que cambie una columna no referenciada

Si la clave foránea apunta a categorias.codigo, cambiar categorias.nombre no activa ON UPDATE CASCADE. La acción está asociada al valor referenciado.

Usar cascada para cambiar IDs arbitrariamente

Que el motor pueda propagar un cambio no significa que debas rotar identificadores técnicos. Si un ID define identidad estable, modificarlo sin una razón de negocio complica auditoría, integraciones y referencias externas.

Probar SQLite sin foreign_keys activado

En SQLite, habilita la aplicación de claves foráneas en la conexión. Si no lo haces, una prueba puede hacerte creer que la cascada no funciona o que una referencia inválida es aceptable.

Comprueba lo aprendido

Intermedia · integridad referencial

Cambia el código de Hogar sin romper sus productos

Partiendo de las tablas del ejemplo, cambia el código de categoría HOG por CASA. Después consulta el producto 3 para comprobar qué valor conserva en categoria_codigo.

Criterio de éxito: la fila de Lámpara queda con categoria_codigo = 'CASA' sin actualizar manualmente la tabla hija.

Compatibilidad entre motores

PostgreSQL documenta ON UPDATE con las mismas familias de acciones referenciales que ON DELETE; con CASCADE, el nuevo valor de la columna referenciada se copia a las filas que la referencian. MySQL 8.4 con InnoDB admite ON UPDATE CASCADE, aunque otros motores de almacenamiento pueden tener restricciones adicionales. SQL Server incluye ON UPDATE CASCADE entre sus acciones de integridad referencial. SQLite también lo implementa cuando las claves foráneas están activas.

Los detalles de NO ACTION, RESTRICT, restricciones diferibles, triggers, índices y DDL cambian entre motores. Por eso conviene verificar la documentación del motor y versión concretos antes de cambiar una restricción en producción.

Qué debes recordar

  • ON UPDATE CASCADE propaga un cambio de la clave referenciada desde el padre hacia sus filas hijas.
  • Solo se activa cuando cambia la columna o combinación de columnas referenciada.
  • Es útil cuando una clave puede cambiar sin cambiar la identidad lógica del registro.
  • Una clave técnica estable puede evitar la necesidad de cascadas de actualización en muchos diseños.
  • No uses CASCADE para ocultar un modelo dudoso: primero decide qué representa la identidad.
  • En SQLite, activa y comprueba la aplicación de claves foráneas en la conexión.

Conceptos relacionados

Fuentes técnicas consultadas