Contenido de esta guía
Qué protege una clave foránea
Una FOREIGN KEY relaciona una o varias columnas de una tabla hija con una clave de otra tabla, normalmente una PRIMARY KEY o una combinación UNIQUE. Su objetivo es conservar la integridad referencial.
En una relación entre clientes y pedidos, pedidos.cliente_id puede referenciar clientes.id. Así, un pedido no puede guardar el identificador de un cliente inexistente.
Estructura básica
CREATE TABLE clientes_demo (
id INTEGER PRIMARY KEY,
nombre VARCHAR(100) NOT NULL
);
CREATE TABLE pedidos_demo (
id INTEGER PRIMARY KEY,
cliente_id INTEGER NOT NULL,
total DECIMAL(10, 2) NOT NULL,
FOREIGN KEY (cliente_id) REFERENCES clientes_demo(id)
);La columna hija y la columna referenciada deben representar el mismo dato y usar tipos compatibles. El nombre de las columnas puede ser distinto; lo importante es la relación declarada.
Qué acepta y qué rechaza
INSERT INTO clientes_demo (id, nombre)
VALUES (1, 'Lucía');
INSERT INTO pedidos_demo (id, cliente_id, total)
VALUES (101, 1, 49.90);
INSERT INTO pedidos_demo (id, cliente_id, total)
VALUES (102, 99, 20.00);| Operación | Resultado |
|---|---|
| Pedido 101 para cliente 1 | Aceptado |
| Pedido 102 para cliente 99 | Rechazado: no existe ese cliente |
La clave foránea no copia los datos del cliente dentro del pedido. Solo comprueba que el valor referenciado sea válido.
Qué ocurre al modificar la fila padre
Puedes declarar acciones para un borrado o una actualización de la clave referenciada:
NO ACTION: no corrige automáticamente las filas hijas; si la relación sigue siendo inválida cuando se comprueba la restricción, la operación falla. En motores que permiten diferir la comprobación, puede existir margen dentro de la transacción para restaurar la integridad antes de ese momento.RESTRICT: rechaza antes el borrado o la actualización de una fila referenciada. PostgreSQL y SQLite documentan que esta comprobación no se difiere del mismo modo queNO ACTION.CASCADE: propaga el borrado o el cambio a las filas hijas.SET NULL: conserva la fila hija y elimina su referencia, siempre que la columna acepteNULL.
No elijas CASCADE por comodidad. Úsalo solo cuando borrar el registro padre deba borrar realmente los registros hijos según las reglas del dominio. Una transacción y una copia de seguridad siguen siendo necesarias en operaciones destructivas.
Error frecuente
Confundir relación con unicidad
cliente_id INTEGER UNIQUE
REFERENCES clientes_demo(id)UNIQUE permitiría como máximo un pedido por cliente. En una relación uno-a-muchos, la clave foránea debe repetirse en tantas filas hijas como corresponda.
Comprueba lo aprendido
Relaciona libros y préstamos
Completa la definición de prestamos para que libro_id apunte a libros(id) y no acepte valores ausentes.
libro_id como INTEGER NOT NULL.libros.FOREIGN KEY (...) REFERENCES ...(...).Solución razonada
CREATE TABLE prestamos (
id INTEGER PRIMARY KEY,
libro_id INTEGER NOT NULL,
socio VARCHAR(100) NOT NULL,
FOREIGN KEY (libro_id) REFERENCES libros(id)
);NOT NULL exige una referencia y FOREIGN KEY exige que esa referencia exista.
Compatibilidad entre motores
La sintaxis central está ampliamente disponible, pero el momento de comprobación, las acciones permitidas, la indexación y la configuración pueden variar. En SQLite debes activar explícitamente la aplicación de claves foráneas en cada conexión con PRAGMA foreign_keys = ON y no depender del valor predeterminado de la compilación.
Qué debes recordar
- La clave foránea protege una relación entre tabla hija y tabla padre.
- No convierte la columna en única.
RESTRICTyNO ACTIONpueden producir el mismo rechazo final, pero no siempre se comprueban en el mismo momento.- Las acciones de borrado deben reflejar las reglas reales del dominio.
- Comprueba que la aplicación de restricciones esté activa en tu entorno.