¡Bienvenido a una de las lecciones clave de nuestro curso! Hoy vamos a hablar sobre cómo crear claves foráneas en PostgreSQL. Este tema es súper importante en el diseño de bases de datos, porque las claves foráneas son las que permiten organizar las relaciones entre tablas. Si sientes que pronto te vas a perder en tu futuro "SQL-ciudad", imagina las claves foráneas como puentes que conectan diferentes barrios.
Dicho de forma sencilla, una clave foránea es una columna (o conjunto de columnas) en una tabla que hace referencia a una columna (normalmente la clave primaria) de otra tabla.
Por ejemplo, si tienes dos tablas — students (estudiantes) y courses (cursos), una clave foránea en la tabla courses puede "apuntar" a qué estudiante está inscrito en el curso. Así se crea una relación entre estas tablas.
¿Por qué es importante?
- La clave foránea ayuda a garantizar la integridad de los datos: no puedes meter algo en una tabla si no existe en la otra.
- Hacen que trabajar con los datos sea más fácil. Por ejemplo, al borrar un registro en una tabla, puedes configurar el borrado automático de los registros relacionados en otra.
Sintaxis para crear una clave foránea
Crear una clave foránea en PostgreSQL es fácil — solo necesitas un poco de magia SQL. Aquí tienes la sintaxis básica:
CREATE TABLE tabla_dependiente (
columna_foreign_id DATA_TYPE REFERENCES tabla_padre(columna_id)
);
Vamos a meternos un poco más en los detalles y ver un par de ejemplos.
Ejemplo 1: Tablas students y courses
Imagina que queremos crear una relación entre estudiantes y cursos. Cada curso debe estar relacionado con algún estudiante. Para eso solo tienes que ejecutar esta consulta:
CREATE TABLE students (
student_id SERIAL PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE courses (
course_id SERIAL PRIMARY KEY,
title TEXT NOT NULL,
student_id INT REFERENCES students(student_id)
);
Aquí:
- En la tabla
studentscreamos la clave primariaPRIMARY KEYpara identificar a cada estudiante. - En la tabla
coursesla columnastudent_ides la clave foráneaFOREIGN KEY, que referencia la columnastudent_iden la tablastudents.
Tabla students
| student_id | name |
|---|---|
| 1 | Alice |
| 2 | Bob |
| 3 | Charlie |
Tabla courses
| course_id | title | student_id - FOREIGN KEY |
|---|---|---|
| 1 | SQL Basics | 1 |
| 2 | Algorithms | 1 |
| 3 | Data Structures | 2 |
| 4 | Intro to Python | 3 |
Nota importante
Cuando añades una clave foránea, PostgreSQL crea automáticamente una regla que comprueba que los valores en la clave foránea coincidan con los valores existentes en la tabla indicada. Si intentas meter un valor incorrecto, la base de datos te dará un error.
Aplicación práctica: modelo students, courses y enrollments
Vamos a ver un ejemplo más complicado con una relación "muchos a muchos". Los mismos estudiantes pueden apuntarse a varios cursos, y un curso puede tener muchos estudiantes. Para crear esa relación necesitamos una tabla intermedia.
CREATE TABLE students (
student_id SERIAL PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE courses (
course_id SERIAL PRIMARY KEY,
title TEXT NOT NULL
);
CREATE TABLE enrollments (
enrollment_id SERIAL PRIMARY KEY,
student_id INT REFERENCES students(student_id), -- clave foránea
course_id INT REFERENCES courses(course_id) -- clave foránea
);
Aquí la tabla enrollments conecta las tablas students y courses usando las claves foráneas student_id y course_id.
Insertar datos
-- Añadimos estudiantes
INSERT INTO students (name) VALUES ('Ivan Ivanov'), ('Maria Smirnova');
-- Añadimos cursos
INSERT INTO courses (title) VALUES ('Matematika'), ('Fizika');
-- Inscribimos estudiantes en cursos
INSERT INTO enrollments (student_id, course_id) VALUES (1, 1), (1, 2), (2, 1);
Consulta de datos
Ahora podemos hacer consultas fácilmente para saber qué cursos está haciendo un estudiante o qué estudiantes están inscritos en un curso concreto:
-- Cursos en los que está inscrito Ivan Ivanov
SELECT c.title
FROM enrollments e
JOIN courses c ON e.course_id = c.course_id
WHERE e.student_id = 1;
-- Estudiantes inscritos en el curso "Matematika"
SELECT s.name
FROM enrollments e
JOIN students s ON e.student_id = s.student_id
WHERE e.course_id = 1;
Opciones avanzadas: ON DELETE y ON UPDATE
La clave foránea también debe controlar el comportamiento de la tabla cuando se modifican o eliminan registros en la tabla padre. Para eso se usan los modificadores ON DELETE y ON UPDATE. Aquí tienes las opciones principales:
- CASCADE: los cambios o eliminaciones en la tabla padre se aplican automáticamente a los registros hijos.
- SET NULL: los valores de la clave foránea en la tabla hija se ponen a
NULL. - RESTRICT: prohíbe borrar o modificar datos si ya se están usando en la tabla hija dependiente.
- NO ACTION: básicamente igual que
RESTRICT, pero la comprobación se hace más tarde.
Ejemplo 2: Usando ON DELETE CASCADE
Imagina que queremos que al borrar un estudiante de la tabla students se borren automáticamente todos sus cursos de la tabla courses. Así se hace:
CREATE TABLE students (
student_id SERIAL PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE courses (
course_id SERIAL PRIMARY KEY,
title TEXT NOT NULL,
student_id INT REFERENCES students(student_id) ON DELETE CASCADE
);
Ahora, si borras un estudiante de la tabla students, todos los registros relacionados con ese estudiante en la tabla courses también se borrarán. Por ejemplo:
INSERT INTO students (name) VALUES ('Ivan Ivanov');
INSERT INTO courses (title, student_id) VALUES ('Matematika', 1), ('Fizika', 1);
-- Borrar al estudiante Ivanov
DELETE FROM students WHERE student_id = 1;
-- La tabla courses ahora estará vacía, porque todos los cursos relacionados con Ivanov se han borrado
Una vez más y con más detalle veremos este tema en la próxima lección.
Proceso de validación de datos al usar claves foráneas
Cuando creas una clave foránea, PostgreSQL se pone en modo portero estricto y revisa cada nuevo registro. Por ejemplo:
- Si intentas insertar un registro con un valor de clave foránea que no existe, te dará un error.
- Si borras un registro en la tabla padre que está relacionado con otras tablas (sin
ON DELETE CASCADE), eso causará un fallo de integridad de datos.
Ejemplo: intento de insertar datos incorrectos
-- Intento de inscribir un curso a un estudiante que no existe
INSERT INTO enrollments (student_id, course_id) VALUES (3, 1);
-- Error: violación de restricción de clave foránea
Errores típicos al crear claves foráneas
- Falta de índice en la clave foránea. PostgreSQL crea automáticamente un índice para la clave primaria, pero no para la foránea. Si vas a usar mucho la clave foránea en condiciones
WHERE, crea el índice tú mismo. - Orden incorrecto al crear tablas. No puedes crear una clave foránea que apunte a una tabla que aún no existe.
- Olvidar el modificador
ON DELETEoON UPDATE. Esto puede causar comportamientos inesperados al editar datos.
Ahora que sabes cómo crear claves foráneas, tienes una herramienta potente para crear bases de datos estructuradas y coherentes. En la próxima lección veremos más a fondo las acciones ON DELETE CASCADE y ON UPDATE RESTRICT para gestionar datos relacionados.
GO TO FULL VERSION