Relaciones · integridad referencial

FOREIGN KEY

Impide que una relación apunte a una fila que no existe en la tabla referenciada.

Lectura: 6–8 minEjemplo comprobadoDecisiones de borrado
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

SQL
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

SQL
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);
Comportamiento comprobado con las claves foráneas activadas en SQLite
OperaciónResultado
Pedido 101 para cliente 1Aceptado
Pedido 102 para cliente 99Rechazado: 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 que NO 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 acepte NULL.

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

Definición problemática
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

Básica · modelado

Relaciona libros y préstamos

Completa la definición de prestamos para que libro_id apunte a libros(id) y no acepte valores ausentes.

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.
  • RESTRICT y NO ACTION pueden 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.

Conceptos relacionados

Fuentes técnicas consultadas