Lecciones del módulo (2/4)
Restricciones múltiples y a nivel de tabla
Garantizar que los datos de la base de datos sean correctos en la capa más básica ("integridad de los datos") es fundamental. Si solo escribe seguridad en la aplicación Node.js, los errores podrían causar datos inconsistentes en la base de datos. Las limitaciones a nivel DDL son la última e impenetrable línea de defensa.
Las principales limitaciones
Además de PRIMARY KEY (que hace que una columna sea única y NO NULA) y los clásicos NOT NULL y UNIQUE, existen dos categorías fundamentales para la coherencia lógica de los datos:
1. CLAVE EXTRANJERA (Integridad referencial)
Una restricción REFERENCES garantiza que realmente exista un ID de enlace en la tabla "principal" a la que apunta.
Por ejemplo, un pedido debe estar vinculado a un cliente existente.
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
customer_id INTEGER REFERENCES customers(id)
);¿Qué hace la clave externa?
- Impide insertar un
customer_idque no existe encustomers. - Te impide
DELETE(eliminar) un cliente decustomerssi hay pedidos apuntando a él (protege contra registros "huérfanos").
También podemos decidir qué debería suceder cuando se elimine el "padre":
customer_id INTEGER REFERENCES customers(id) ON DELETE CASCADECon ON DELETE CASCADE, si eliminamos al cliente, Postgres eliminará automáticamente todos los orders vinculados. (Úselo con mucha precaución; normalmente es preferible la configuración predeterminada que bloquea la operación).
2. COMPROBAR Restricciones
Una restricción CHECK valida la fila probando una expresión booleana antes de proceder a guardar.
CREATE TABLE contratti (
id SERIAL PRIMARY KEY,
stipendio NUMERIC(10,2) CHECK (stipendio > 0),
data_inizio DATE,
data_fine DATE,
CHECK (data_fine > data_inizio)
);El primer CHECK es una restricción de columna (solo se refiere a stipendio).
El segundo CHECK en la parte inferior es una restricción de tabla (puede cruzar valores de varias columnas y debe declararse en la parte inferior).
Si un INSERT o UPDATE intenta guardar el final antes del inicio, ¡Postgres lo rechazará con un error!
Restricciones de nombres
A menudo es una buena práctica dar a las restricciones un nombre explícito (usando la palabra clave CONSTRAINT). De esta manera, cuando Postgres bloquee un registro, el error le dirá, por ejemplo, "restricción 'stipendio_positivo' violada", ¡lo cual es mucho más claro para la depuración!
CREATE TABLE prodotti (
id SERIAL PRIMARY KEY,
nome VARCHAR(50),
CONSTRAINT nome_univoco UNIQUE(nome)
);Pruébalo
Cree una tabla 'prenotazioni' con id (SERIAL PRIMARY KEY) y un 'customer_id' (INTEGER). Utilice CONSTRAINT fk_cliente FOREIGN KEY (customer_id) REFERENCES clientes(id) para dar un nombre explícito a la restricción de clave externa. Hazlo en la parte inferior, como una restricción de la tabla.
Mostrar pista
Escribir RESTRICCIÓN fk_cliente CLAVE EXTRANJERA (columna_local) REFERENCIAS tabla_externa(col_externa)
Solución disponible después de 3 intentos
Restricciones con lógica personalizada
Cree una tabla 'eventi' con id (SERIAL PRIMARY KEY), posti_totali (INTEGER) y biglietti_venduti (INTEGER). Agregue una restricción de tabla llamada 'check_capienza' donde biglietti_venduti nunca debe ser mayor que posti_totali.
Mostrar pista
Agregue la restricción en la parte inferior usando CONSTRAINT check_capienza CHECK (expresión)
Solución disponible después de 3 intentos