Constraint

Qué es un constraint

Un constraint (restricción) es una regla que el SGBD hace cumplir automáticamente para proteger la integridad de los datos.
Si una instrucción INSERT/UPDATE viola la regla, la operación falla y la base no queda en un estado inválido.

Tres grandes objetivos que cubren los constraints:

  • Dominio: que cada columna tenga valores válidos (tipo, rango, obligatoriedad).
  • Entidad: que cada fila sea identificable de forma única.
  • Referencia: que las relaciones entre tablas se mantengan coherentes.

Tipos de constraints (estándar SQL)

  1. NOT NULL – prohíbe valores nulos en una columna.
  2. UNIQUE – asegura que no se repitan valores (puede ser de una o varias columnas).
  3. PRIMARY KEY – identifica de forma única a cada fila (implícitamente NOT NULL + UNIQUE).
  4. FOREIGN KEY – obliga a que un valor exista previamente en la tabla referenciada (integridad referencial).
  5. CHECK – valida una condición booleana (rango, patrón, consistencia simple).

Nota de versiones: CHECK se enfuerza en MySQL ≥ 8.0.16 y MariaDB ≥ 10.2.x. En versiones más antiguas se ignoraba o requería alternativas (triggers).

Ejemplos rápidos (MariaDB/MySQL)

A. Definir constraints al crear tablas

CREATE TABLE student (
  student_id   INT AUTO_INCREMENT,
  student_code VARCHAR(20) NOT NULL,         -- NOT NULL
  email        VARCHAR(255) UNIQUE,          -- UNIQUE
  PRIMARY KEY (student_id),                  -- PRIMARY KEY
  CONSTRAINT uq_student_code UNIQUE (student_code),   -- UNIQUE nombrado
  CONSTRAINT chk_code_len CHECK (CHAR_LENGTH(student_code) >= 3) -- CHECK
) ENGINE=InnoDB;
 
CREATE TABLE course (
  course_id INT AUTO_INCREMENT PRIMARY KEY,
  code      VARCHAR(20) NOT NULL UNIQUE,
  credits   TINYINT NOT NULL,
  CONSTRAINT chk_credits CHECK (credits BETWEEN 1 AND 10)
) ENGINE=InnoDB;
 
CREATE TABLE enrollment (
  student_id INT NOT NULL,
  course_id  INT NOT NULL,
  enrolled_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (student_id, course_id),                 -- UNIQUE del par
  CONSTRAINT fk_enr_student FOREIGN KEY (student_id)
    REFERENCES student(student_id) ON DELETE CASCADE,
  CONSTRAINT fk_enr_course  FOREIGN KEY (course_id)
    REFERENCES course(course_id)  ON DELETE RESTRICT
) ENGINE=InnoDB;

B. Añadir o quitar constraints después (ALTER TABLE)

-- Agregar UNIQUE compuesto
ALTER TABLE student
  ADD CONSTRAINT uq_student_name_email UNIQUE (full_name, email);
 
-- Agregar FOREIGN KEY
ALTER TABLE enrollment
  ADD CONSTRAINT fk_enr_course FOREIGN KEY (course_id)
  REFERENCES course(course_id) ON DELETE RESTRICT;
 
-- Quitar una FOREIGN KEY (usa su nombre)
ALTER TABLE enrollment DROP FOREIGN KEY fk_enr_course;
 
-- Quitar un UNIQUE en MySQL/MariaDB se hace como índice:
ALTER TABLE student DROP INDEX uq_student_name_email;
 
-- Quitar un CHECK (MySQL 8+)
ALTER TABLE course DROP CHECK chk_credits;

¿Por qué usar constraints y no sólo validación en la app?

  • Consistencia centralizada: protegen los datos aunque haya múltiples aplicaciones o usuarios conectados.
  • Atómicas: se aplican dentro de la transacción; no hay “ventanas” para estados inválidos.
  • Performance: PRIMARY KEY y UNIQUE crean índices útiles; las FK suelen beneficiarse de índices en las columnas referenciadas.

Buenas prácticas

  • Nombra tus constraints (fk_enr_course, chk_credits): facilita depurar y alterar.
  • Usa NOT NULL por defecto salvo que nulo tenga un significado claro.
  • Prefiere UNIQUE multicolumna para reglas como “no hay dos matrículas del mismo estudiante en el mismo curso”.
  • Define ON DELETE/UPDATE en FKs de acuerdo al negocio (CASCADE, RESTRICT, SET NULL).
  • CHECK para reglas de dominio (rangos, formatos). Para reglas complejas que cruzan varias filas/ tablas, evalúa triggers.
  • Índices para FKs: añade un índice en la columna que referencia; mejora JOIN y borrados/actualizaciones en cascada.

Errores típicos

  • Confiar sólo en la app: otro cliente puede saltarse la validación.
  • CHECK en versiones antiguas de MySQL/MariaDB → no se aplicaba (ver tu versión).
  • Falta de índices en FKs → JOIN lentos y cascadas costosas.
  • PRIMARY KEY no estable (p. ej., usar un dato que cambia). Mejor surrogate key (AUTO_INCREMENT) y UNIQUE para la llave natural.