Llaves Primarias y Foráneas

🔑 ¿Qué son las llaves?

Las llaves permiten identificar y conectar registros entre tablas:

  • Llave Primaria (PK): identifica unívocamente cada fila.
  • Llave Foránea (FK): conecta una tabla con otra (apunta a la PK de otra tabla).

🟡 Llave primaria (PK) — idea central

  • Debe ser única y no nula.
  • Debe ser estable (no cambiar con el tiempo).
  • Debe ser minimal (solo lo necesario).
🟡 id_curso nombre precio
CUR001 SQL Básico 300000
CUR002 Java Inicial 400000
CUR003 Python Pro 500000

🧩 Llave foránea (FK) — idea central

  • Es un campo que apunta a la PK de otra tabla.
  • Sirve para enlazar datos y garantizar integridad referencial.
id_prof nombre
P01 López
P02 García
id_curso nombre id_prof
CUR001 SQL Básico P01
CUR002 SQL Avanzado P01
CUR003 Python Pro P02

🎬 De tablas simples a PK/FK

Paso 1. Tablas base (sin llaves)

%%{init: {'er': {'layoutDirection': 'LR'}}}%%
erDiagram
  PROFESOR {
    STRING nombre
  }

  CURSO {
    STRING nombre
    INT precio
  }

  ESTUDIANTE {
    STRING nombre
    STRING apellido
  }

🎬 Paso 2 — Añadimos las PK

%%{init: {'er': {'layoutDirection': 'LR'}}}%%
erDiagram
  PROFESOR {
    STRING id_prof PK
    STRING nombre
  }

  CURSO {
    STRING id_curso PK
    STRING nombre
    INT precio
  }

  ESTUDIANTE {
    STRING id_est PK
    STRING nombre
    STRING apellido
  }

🎬 Paso 3 — Incorporamos las FK y relaciones

%%{init: {'er': {'layoutDirection': 'LR', 'fontSize': 16}}}%%
erDiagram
  PROFESOR {
    STRING id_prof PK
    STRING nombre
  }

  CURSO {
    STRING id_curso PK
    STRING nombre
    INT precio
    STRING id_prof FK
  }

  ESTUDIANTE {
    STRING id_est PK
    STRING nombre
    STRING apellido
  }

  CURSO_EST {
    STRING id_est FK
    STRING id_curso FK
  }

  PROFESOR ||--o{ CURSO : "dicta"
  ESTUDIANTE ||--o{ CURSO_EST : "se inscribe"
  CURSO ||--o{ CURSO_EST : "tiene"

🧠 Claves compuestas (PK con varias columnas)

A veces la identidad natural es combinada:

  • Ejemplo: (id_est, id_curso) identifica una inscripción.

  • Ventaja: evita crear un ID artificial si la combinación ya es única.

  • Cuidado: puede complicar otras FKs y joins.

Vista conceptual (PK compuesta):

id_est id_curso fecha
EST01 CUR001 2025-03-01
EST01 CUR002 2025-03-05
EST02 CUR001 2025-03-06

🧷 Integridad referencial (qué pasa si…)

Cuando una PK cambia o se elimina, ¿qué hacer con las FKs relacionadas?

  • RESTRICT / NO ACTION: no permite borrar/editar si hay hijos.
  • CASCADE: propaga el cambio a las filas hijas.
  • SET NULL: pone la FK en NULL en los hijos.
  • SET DEFAULT: asigna un valor por defecto.

💡 Elige según la lógica del negocio (por ejemplo, no “borres” profesores con cursos activos).

🔗 Integridad referencial: ¿qué pasa con las FKs?

Situación base: Un profesor dicta cursos.

PROFESOR

id_prof nombre
P01 López
P02 García

CURSO

id_curso nombre id_prof
C01 SQL Básico P01
C02 SQL Avanzado P01
C03 Python Pro P02

🧯 RESTRICT / NO ACTION

No se permite borrar/editar la PK si hay “hijos” que la usan.

Intento: borrar P01 Resultado:Error (existen cursos C01, C02 apuntando a P01)

PROFESOR (sin cambios)

id_prof nombre
P01 López
P02 García

CURSO (sin cambios)

id_curso nombre id_prof
C01 SQL Básico P01
C02 SQL Avanzado P01
C03 Python Pro P02

💡 Útil cuando no debe existir un curso sin profesor válido.

🌊 CASCADE

El cambio en la PK se propaga a las filas hijas.

Acción: borrar P01 Resultado: ✅ se borran también C01 y C02 (hijos de P01)

PROFESOR

id_prof nombre
P02 García

CURSO

id_curso nombre id_prof
C03 Python Pro P02

💡 Útil cuando un “padre” y sus “hijos” deben vivir o morir juntos.

🕳️ SET NULL

Al borrar/editar la PK, la FK en hijos se vuelve NULL.

Acción: borrar P01 Resultado: C01 y C02 quedan sin profesor (FK a NULL)

PROFESOR

id_prof nombre
P02 García

CURSO

id_curso nombre id_prof
C01 SQL Básico (NULL)
C02 SQL Avanzado (NULL)
C03 Python Pro P02

💡 Útil si los cursos pueden quedar “huérfanos” temporalmente (asignarás profe luego).

🧩 SET DEFAULT

La FK en hijos toma un valor por defecto predefinido.

Acción: borrar P01 Resultado: C01 y C02 pasan a id_prof = P00 (profe “Por asignar”)

PROFESOR

id_prof nombre
P00 Por asignar
P02 García

CURSO

id_curso nombre id_prof
C01 SQL Básico P00
C02 SQL Avanzado P00
C03 Python Pro P02

💡 Útil cuando el negocio exige un valor válido siempre (nunca NULL).

🎯 ¿Cuál elegir?

  • RESTRICT / NO ACTION → protege la coherencia estricta (no huérfanos).
  • CASCADE → mantiene integridad en bloque (padre e hijos inseparables).
  • SET NULL → permite vacíos temporales para reasignar después.
  • SET DEFAULT → garantiza referencias válidas con un fallback.

👉 Elige según la lógica del negocio (p. ej., no borres profesores con cursos activos si tu regla es mantener historia).

🧪 Mini-quiz

  1. Si un profesor renuncia pero los cursos deben continuar, ¿qué aplicarías?
    1. RESTRICT b) CASCADE c) SET NULL d) SET DEFAULT
  2. Si eliminar un cliente debe eliminar todos sus pedidos, ¿cuál usas?
    1. RESTRICT b) CASCADE c) SET NULL d) SET DEFAULT
  3. Si un pedido siempre debe quedar asociado a algún vendedor, incluso temporalmente, ¿qué conviene?
    1. RESTRICT b) CASCADE c) SET NULL d) SET DEFAULT

✅ Buenas prácticas con PK/FK

  • PK cortas y estables (IDs tipo CUR001, UUID, o autoincremento).
  • FK explícitas y con nombres claros (id_prof, id_est).
  • Índices en PK y FKs para acelerar búsquedas.
  • Evita exponer PK sensibles (cédulas/dnis) si pueden cambiar.
  • Prefiere valores atómicos y evita duplicados de información.

🧪 Mini práctica

  1. Marca la PK y la(s) FK en este esquema verbal:
  • “Un pedido tiene muchos ítems; cada ítem pertenece a un pedido”.
  • “Un cliente puede hacer muchos pedidos; cada pedido pertenece a un cliente”.
  1. ¿Harías PK compuesta en ÍTEM (id_pedido, num_item) o un id_item artificial? Justifica.

  2. Si borras un cliente con pedidos, ¿qué política aplicarías? ¿Por qué?