Clave primaria vs clave foránea: diferencias y ejemplos en SQL

Clave primaria vs clave foránea: diferencias y ejemplos en SQL

La clave primaria identifica cada fila de forma única. La clave foránea conecta una tabla con otra y protege la integridad de la relación. Juntas forman la base de un modelo relacional: permiten saber qué pedido pertenece a qué cliente sin repetir todos los datos del cliente en cada venta.

En esta guía verás la diferencia, cómo definir ambas restricciones y qué decisiones tomar ante borrados, actualizaciones y relaciones de muchos a muchos.

Qué es una clave primaria

Una clave primaria o PRIMARY KEY es una columna, o conjunto de columnas, que identifica una fila sin ambigüedad.

Debe ser:

  • única;
  • no nula;
  • estable;
  • mínima: sin columnas innecesarias.
CREATE TABLE clientes (
    cliente_id BIGINT PRIMARY KEY,
    email VARCHAR(255) NOT NULL UNIQUE,
    nombre VARCHAR(150) NOT NULL
);

cliente_id identifica la fila. email también es único, pero no es la clave primaria elegida.

Qué es una clave foránea

Una clave foránea o FOREIGN KEY es una columna que referencia una clave primaria o única de otra tabla:

CREATE TABLE pedidos (
    pedido_id BIGINT PRIMARY KEY,
    cliente_id BIGINT NOT NULL,
    fecha DATE NOT NULL,
    total DECIMAL(12, 2) NOT NULL,
    CONSTRAINT fk_pedidos_cliente
        FOREIGN KEY (cliente_id)
        REFERENCES clientes (cliente_id)
);

La base impide insertar un pedido con un cliente_id inexistente. Eso es integridad referencial.

Diferencias principales

Característica Clave primaria Clave foránea
Propósito Identificar una fila Relacionar tablas
Valores repetidos No Sí, normalmente
NULL No Puede permitirse
Cantidad por tabla Una restricción, simple o compuesta Varias
Referencia A la propia fila A una clave de otra tabla
Índice automático Normalmente sí Depende del motor

Una tabla puede tener una clave primaria compuesta por varias columnas, pero sigue siendo una sola restricción primaria.

Relación uno a muchos

Un cliente puede tener muchos pedidos. El identificador aparece una vez en clientes y muchas veces en pedidos:

clientes.cliente_id  1 ─────── N  pedidos.cliente_id

Para recuperar la información:

SELECT
    p.pedido_id,
    p.fecha,
    p.total,
    c.nombre
FROM pedidos AS p
JOIN clientes AS c
  ON c.cliente_id = p.cliente_id;

Los fundamentos de SQL usan estas relaciones para combinar datos mediante JOIN.

Clave natural vs clave sustituta

Clave natural

Tiene significado de negocio: email, número fiscal, matrícula. Puede cambiar, contener datos sensibles o ser larga.

Clave sustituta

Es un identificador generado sin significado externo: entero autoincremental o UUID.

Un patrón robusto es usar una clave sustituta como primaria y conservar la clave natural con UNIQUE:

CREATE TABLE productos (
    producto_id BIGINT PRIMARY KEY,
    sku VARCHAR(50) NOT NULL UNIQUE,
    nombre VARCHAR(200) NOT NULL
);

Así las relaciones no dependen de que el SKU cambie.

Claves compuestas

En una tabla puente de muchos a muchos:

CREATE TABLE alumno_curso (
    alumno_id BIGINT NOT NULL,
    curso_id BIGINT NOT NULL,
    fecha_inscripcion DATE NOT NULL,
    PRIMARY KEY (alumno_id, curso_id),
    FOREIGN KEY (alumno_id) REFERENCES alumnos (alumno_id),
    FOREIGN KEY (curso_id) REFERENCES cursos (curso_id)
);

La combinación evita inscribir al mismo alumno dos veces en el mismo curso. Cada columna puede repetirse por separado.

Qué ocurre al borrar o actualizar

La acción referencial define el comportamiento:

  • RESTRICT o NO ACTION: bloquea si existen filas hijas.
  • CASCADE: propaga el borrado o actualización.
  • SET NULL: conserva la fila hija y elimina la referencia.
  • SET DEFAULT: usa un valor predeterminado, si el motor y diseño lo permiten.
FOREIGN KEY (cliente_id)
REFERENCES clientes (cliente_id)
ON DELETE RESTRICT
ON UPDATE CASCADE

Usa ON DELETE CASCADE solo cuando la fila hija no tenga sentido sin su padre, por ejemplo líneas de un pedido. En facturación o auditoría, borrar en cascada puede destruir historial valioso.

¿Hay que indexar la clave foránea?

La clave primaria suele crear un índice automáticamente. Una clave foránea no siempre. Indexarla ayuda en:

  • joins;
  • búsquedas por padre;
  • validación de borrados y actualizaciones;
  • bloqueos más acotados en algunos motores.
CREATE INDEX idx_pedidos_cliente
ON pedidos (cliente_id);

No indexes por reflejo todas las columnas: cada índice consume espacio y encarece escrituras. La guía de índices en bases de datos explica el equilibrio.

Errores frecuentes

  • Usar un dato mutable como clave primaria.
  • Crear relaciones solo en el código y no en la base.
  • Elegir tipos distintos entre PK y FK.
  • Permitir huérfanos durante importaciones.
  • Aplicar CASCADE sin revisar el dominio.
  • Olvidar índices en claves foráneas consultadas.
  • Usar una clave compuesta enorme en muchas tablas.
  • Confundir UNIQUE con PRIMARY KEY.

El diseño de una base de datos desde cero ayuda a decidir dónde vive cada entidad y cómo se relaciona.

Preguntas frecuentes

¿Puede una tabla tener varias claves primarias?
No. Tiene una sola restricción PRIMARY KEY, aunque esa clave puede incluir varias columnas.

¿Puede una clave foránea tener valores repetidos?
Sí. Es lo habitual en una relación uno a muchos: varios pedidos pueden compartir el mismo cliente.

¿Una clave foránea puede ser NULL?
Sí, si la relación es opcional y la columna no tiene NOT NULL.

¿La clave foránea debe apuntar siempre a una primaria?
Debe apuntar a una clave candidata única admitida por el motor; normalmente es la primaria, pero puede ser una restricción UNIQUE.

¿Qué diferencia hay entre PRIMARY KEY y UNIQUE?
Ambas garantizan unicidad. La primaria identifica oficialmente la fila y no admite NULL; el tratamiento de NULL en UNIQUE varía por motor.

¿Conviene usar UUID o entero como clave primaria?
Depende de distribución, escala y exposición. Los enteros son compactos; UUID facilita generación distribuida, pero ocupa más y puede afectar índices.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir