Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/tutosrive/db-relacionales-2026-1/llms.txt

Use this file to discover all available pages before exploring further.

La integridad de los datos es uno de los pilares fundamentales de las bases de datos relacionales. Sin restricciones, nada impide que un curso referencie un profesor que no existe, que un alumno tenga un género inválido, o que dos registros compartan el mismo identificador. PostgreSQL ofrece un conjunto completo de mecanismos de restricción que se verifican automáticamente en cada operación de escritura, rechazando los datos que violan las reglas definidas. En este taller explorarás cada tipo de restricción con ejemplos reales, aprenderás a definir claves primarias y foráneas compuestas, y entenderás los distintos comportamientos disponibles cuando se eliminan o actualizan registros referenciados.

Tipos de restricciones

Clave primaria (PRIMARY KEY)

La clave primaria identifica de forma única cada fila de una tabla. Internamente, PostgreSQL crea un índice UNIQUE sobre las columnas que la componen e impone NOT NULL en todas ellas. Puede ser simple (una columna) o compuesta (varias columnas).Clave primaria simple:
CREATE TABLE IF NOT EXISTS table1 (
  a VARCHAR(1),
  b VARCHAR(1),
  CONSTRAINT pk_table1 PRIMARY KEY (a)
);
INSERT INTO table1 (a, b) VALUES ('a', 'b');
En table1, la columna a es la clave primaria. Intentar insertar dos filas con el mismo valor en a generará un error.Clave primaria compuesta:
CREATE TABLE IF NOT EXISTS table3 (
  c VARCHAR(1),
  d INT,
  e VARCHAR(1),
  CONSTRAINT pk_table3 PRIMARY KEY (c, d)
);
INSERT INTO table3 (c, d, e) VALUES ('x', 1, 'w'), ('x', 2, 'z');
En table3, la clave primaria es el par (c, d). Observa que el valor 'x' en la columna c se repite en ambas filas: eso es válido porque la unicidad se evalúa sobre la combinación de c y d, no sobre cada columna por separado.Prueba de violación:
-- Esto falla: (c='x', d=1) ya existe
INSERT INTO table3 (c, d, e) VALUES ('x', 1, 'duplicado');
Nombrar las restricciones explícitamente (usando CONSTRAINT nombre_restriccion) facilita enormemente la depuración: los mensajes de error mostrarán el nombre de la restricción violada en lugar de un identificador generado automáticamente.

Claves primarias y foráneas compuestas

El siguiente ejemplo integra los tres conceptos clave del taller: PK simple, PK compuesta y FK compuesta trabajando en conjunto.
-- Tabla con PK simple
CREATE TABLE IF NOT EXISTS table1 (
  a VARCHAR(1),
  b VARCHAR(1),
  CONSTRAINT pk_table1 PRIMARY KEY (a)
);
INSERT INTO table1 (a, b) VALUES ('a', 'b');
-- Tabla con PK compuesta
CREATE TABLE IF NOT EXISTS table3 (
  c VARCHAR(1),
  d INT,
  e VARCHAR(1),
  CONSTRAINT pk_table3 PRIMARY KEY (c, d)
);
INSERT INTO table3 (c, d, e) VALUES ('x', 1, 'w'), ('x', 2, 'z');
-- Tabla con PK compuesta y dos FK (una simple, una compuesta)
CREATE TABLE IF NOT EXISTS table2 (
  a VARCHAR(1),
  c VARCHAR(1),
  d INT,
  CONSTRAINT pk_table2 PRIMARY KEY (a, c, d),
  CONSTRAINT fk_a_t2 FOREIGN KEY (a) REFERENCES table1 (a),
  CONSTRAINT fk_c_t2 FOREIGN KEY (c, d) REFERENCES table3 (c, d)
);
INSERT INTO table2 (a, c, d) VALUES ('a', 'x', 1), ('a', 'x', 2);
En este diseño:
  • table2.a referencia la PK simple de table1.
  • table2.(c, d) referencia la PK compuesta de table3 — ambas columnas deben coincidir simultáneamente con una fila existente.
  • La PK de table2 es la combinación de los tres campos (a, c, d).

Errores comunes y sus causas

Mensaje: ERROR: null value in column "X" of relation "Y" violates not-null constraintCausa: Se intentó insertar o actualizar con NULL en una columna declarada NOT NULL.Solución: Provee un valor explícito para la columna o verifica que no estés omitiendo una columna requerida en el INSERT.
Mensaje: ERROR: duplicate key value violates unique constraint "pk_X"Causa: Ya existe una fila con el mismo valor (o combinación de valores) en la clave primaria.Solución: Verifica si el registro ya existe antes de insertar. Considera usar INSERT ... ON CONFLICT DO NOTHING si el duplicado es esperado.
Mensaje: ERROR: insert or update on table "X" violates foreign key constraint "fk_Y"Causa: El valor que se intenta insertar en la columna foránea no existe en la tabla referenciada (tabla padre).Solución: Asegúrate de que el registro padre exista antes de insertar en la tabla hija. Verifica el valor con un SELECT en la tabla padre.
Mensaje: ERROR: new row for relation "X" violates check constraint "ck_Y"Causa: El valor insertado o actualizado no cumple la expresión booleana definida en el CHECK.Solución: Revisa la definición del CHECK con \d nombre_tabla en psql o consultando information_schema.table_constraints. Ajusta el valor al rango o conjunto permitido.
Mensaje: ERROR: update or delete on table "X" violates foreign key constraint "fk_Y" on table "Z"Causa: Se intentó eliminar o modificar una fila en la tabla padre que tiene filas hijas dependientes, y la FK no tiene CASCADE configurado.Solución: Primero elimina o actualiza las filas hijas, o redefine la FK con ON DELETE CASCADE / ON DELETE SET NULL si el comportamiento automático es apropiado para tu modelo de datos.
Mensaje: ERROR: there is no unique constraint matching given keys for referenced table "X"Causa: La columna o columnas referenciadas en el REFERENCES no tienen una restricción PRIMARY KEY o UNIQUE.Solución: Las FKs solo pueden referenciar columnas que sean PK o tengan restricción UNIQUE. Agrega la restricción faltante en la tabla padre.

Consultar restricciones existentes

Puedes inspeccionar todas las restricciones de tu base de datos con estas consultas:
-- Ver todas las restricciones de una tabla específica
SELECT
  constraint_name,
  constraint_type
FROM information_schema.table_constraints
WHERE table_name = 'cursos';

-- Ver las columnas involucradas en cada restricción
SELECT
  tc.constraint_name,
  tc.constraint_type,
  kcu.column_name
FROM information_schema.table_constraints tc
JOIN information_schema.key_column_usage kcu
  ON tc.constraint_name = kcu.constraint_name
WHERE tc.table_name = 'table2'
ORDER BY tc.constraint_name, kcu.ordinal_position;

-- Ver las FK y sus tablas referenciadas
SELECT
  tc.constraint_name,
  kcu.column_name,
  ccu.table_name AS tabla_referenciada,
  ccu.column_name AS columna_referenciada
FROM information_schema.table_constraints tc
JOIN information_schema.key_column_usage kcu
  ON tc.constraint_name = kcu.constraint_name
JOIN information_schema.constraint_column_usage ccu
  ON tc.constraint_name = ccu.constraint_name
WHERE tc.constraint_type = 'FOREIGN KEY'
  AND tc.table_name = 'cursos';

Build docs developers (and LLMs) love