CodeGym /Cursos /SQL SELF /Uso de ON DELETE CASCADE y ON UPDATE...

Uso de ON DELETE CASCADE y ON UPDATE RESTRICT

SQL SELF
Nivel 19 , Lección 2
Disponible

Imagina que has creado una base de datos donde tienes una tabla de clientes (customers) y pedidos relacionados (orders). Pero en algún momento surge la pregunta: ¿qué pasa si borras un cliente de la tabla customers? ¿Deberían borrarse también sus pedidos, o se quedarían "huérfanos", apuntando a un cliente que ya no existe? ¿Y si decides cambiar el ID del cliente? Aquí es donde entran en juego las operaciones en cascada (CASCADE) y las restricciones (RESTRICT) para controlar el comportamiento de la base de datos.

ON DELETE CASCADE es un mecanismo que borra automáticamente los registros relacionados cuando borras un registro de la tabla padre. O sea, si borras un cliente, todos sus pedidos también se borran.

Funciona así: cuando añades ON DELETE CASCADE en la definición de la clave foránea, la base de datos "entiende" que el registro relacionado debe borrarse automáticamente.

Ejemplo

Supón que tenemos dos tablas: customers y orders. Los clientes (customers) pueden hacer varios pedidos (orders), lo que corresponde a una relación ONE-TO-MANY. Queremos que, al borrar un cliente, todos sus pedidos también se borren.

-- Creamos la tabla de clientes
CREATE TABLE customers (
    customer_id SERIAL PRIMARY KEY,
    name TEXT NOT NULL
);

-- Creamos la tabla de pedidos con una clave foránea que referencia a la tabla de clientes
CREATE TABLE orders (
    order_id SERIAL PRIMARY KEY,
    customer_id INT REFERENCES customers(customer_id) ON DELETE CASCADE,
    order_date DATE NOT NULL
);

Insertamos datos en las tablas

-- Insertamos datos en la tabla de clientes
INSERT INTO customers (name) VALUES ('Iván'), ('Anna');

-- Insertamos datos en la tabla de pedidos
INSERT INTO orders (customer_id, order_date) VALUES
(1, '2023-10-01'),
(1, '2023-10-02'),
(2, '2023-10-03');

Tabla orders:

order_id customer_id order_date
1 1 2023-10-01
2 1 2023-10-02
3 2 2023-10-03

Borramos un cliente y vemos qué pasa

-- Borramos el cliente con ID 1
DELETE FROM customers WHERE customer_id = 1;

-- Comprobamos qué queda en la tabla de pedidos
SELECT * FROM orders;
order_id customer_id order_date
3 2 2023-10-03

Como ves, los pedidos relacionados con el cliente borrado también se eliminaron.

Restringiendo cambios: ON UPDATE RESTRICT

ON UPDATE RESTRICT te permite evitar que se cambie un valor en la tabla padre si hay un registro en la tabla hija que lo referencia. Es como una "barrera de protección" que impide cambios que podrían romper la integridad de los datos.

¿Cómo funciona? Cuando añades ON UPDATE RESTRICT, la base de datos no te dejará actualizar la clave en la tabla padre si hay registros en la tabla hija que la usan.

Ejemplo

Usamos las mismas tablas customers y orders, pero ahora añadimos la restricción de actualización a la clave foránea.

-- Volvemos a crear la tabla de pedidos con restricción en la actualización
DROP TABLE orders;

CREATE TABLE orders (
    order_id SERIAL PRIMARY KEY,
    customer_id INT REFERENCES customers(customer_id) ON UPDATE RESTRICT,
    order_date DATE NOT NULL
);

Intentamos actualizar el ID del cliente

-- Intento de cambiar el ID del cliente de 2 a 5
UPDATE customers 
SET customer_id = 5 
WHERE customer_id = 2;

Resultado:

ERROR:  update or delete on table "customers" violates foreign key constraint
DETAIL:  Key (customer_id)=(2) is still referenced from table "orders".

Como puedes ver, la base de datos lanzó un error porque el cambio de clave rompería la relación entre las tablas.

Te cuento más sobre UPDATE y sus detalles en el siguiente nivel :P

Combinando ON DELETE CASCADE y ON UPDATE RESTRICT

Obviamente, puedes combinar operaciones en cascada (CASCADE) y restricciones (RESTRICT). Por ejemplo, puedes configurar el borrado automático de datos relacionados al eliminar el registro padre (ON DELETE CASCADE), pero a la vez prohibir cambiar su ID (ON UPDATE RESTRICT) para evitar líos.

Ejemplo

Vamos a crear otra vez la tabla de pedidos usando ambos mecanismos:

DROP TABLE orders;

CREATE TABLE orders (
    order_id SERIAL PRIMARY KEY,
    customer_id INT REFERENCES customers(customer_id)
        ON DELETE CASCADE
        ON UPDATE RESTRICT,
    order_date DATE NOT NULL
);

Ahora:

  • Si borras un cliente, todos sus pedidos se borran.
  • Si intentas cambiar el ID del cliente, te dará error.

¿Por qué es importante esto en proyectos reales?

Usar CASCADE y RESTRICT es super importante en sistemas grandes con muchas tablas relacionadas. Por ejemplo:

En una tienda online, un cliente puede tener pedidos. Si el cliente decide borrar su perfil, no quieres dejar pedidos en la base de datos que ya no apuntan a nadie. Aquí te salva ON DELETE CASCADE.

Al mismo tiempo, puede que quieras evitar cambios accidentales en claves únicas para no romper las relaciones entre tablas. Para eso sirve ON UPDATE RESTRICT.

2
Tarea
SQL SELF, nivel 19, lección 2
Bloqueada
Creación de tablas con `ON DELETE CASCADE`
Creación de tablas con `ON DELETE CASCADE`
2
Tarea
SQL SELF, nivel 19, lección 2
Bloqueada
Añadir la restricción `ON UPDATE RESTRICT`
Añadir la restricción `ON UPDATE RESTRICT`
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION