La constraint CHECK è, in un certo senso, come un buttafuori all’ingresso della tua tabella. Garantisce che i dati che aggiungi rispettino certe condizioni. Se provi a inserire dati che violano queste condizioni, il database non li accetta.
Immagina di voler aprire un negozio in Germania. Ma per legge la domenica è giorno di riposo e non si può vendere nulla. Questa regola è l’analogo di CHECK nel database. Provi a impostare l’orario del negozio: aperto 7 giorni su 7, ma il sistema ti risponde subito: "Nein, nein, domenica è una violazione. Questo orario non passa il controllo!"
Così anche nel database: se imposti un valore che viola la regola CHECK, il sistema lo blocca per evitare un "errore logico" nei dati.
Perché serve CHECK?
- Mantiene la qualità dei dati:
CHECKimpedisce che informazioni sbagliate o illogiche finiscano nella tabella. - Riduce la probabilità di errori: invece di controllare i dati a mano prima di inserirli, puoi lasciare il compito al database.
- Logica autonoma: puoi mettere le regole di controllo direttamente nella struttura del database, senza doverle gestire nel codice dell’applicazione.
Come funziona CHECK?
La constraint CHECK si imposta quando crei la tabella o puoi aggiungerla dopo con il comando ALTER TABLE. Ecco la sintassi base:
CREATE TABLE tabella (
colonna tipo_dati CHECK (condizione)
);
condizione è un’espressione logica che deve essere vera per ogni valore nella colonna indicata. Se la condizione viene violata, il database dà errore.
Esempio 1: Controllo del range di valori
Creiamo la tabella students, dove l’età degli studenti (age) deve essere tra 16 e 100:
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
age INTEGER CHECK (age >= 16 AND age <= 100)
);
Ora, se provi a inserire uno studente con età 12, il database ti "becca subito":
INSERT INTO students (name, age)
VALUES ('Maria Chi', 12);
Errore:
ERROR: new row for relation "students" violates check constraint "students_age_check"
DETAIL: Failing row contains (1, Maria Chi, 12).
Eh sì, il database qui fa il portinaio severo. Se non hai 16 anni, non entri.
Esempio 2: Controllo del formato dei dati
Supponiamo di avere una tabella emails dove salviamo gli indirizzi email. Vogliamo assicurarci che gli indirizzi contengano il simbolo @ (controllo semplificato):
CREATE TABLE emails (
id SERIAL PRIMARY KEY,
email VARCHAR(255) CHECK (email LIKE '%@%')
);
Proviamo ad aggiungere un indirizzo sbagliato che non rispetta la regola:
INSERT INTO emails (email)
VALUES ('notanemail.com');
Errore:
ERROR: new row for relation "emails" violates check constraint "emails_email_check"
DETAIL: Failing row contains (1, notanemail.com).
L’errore si evita se tutti i dati hanno il simbolo @:
INSERT INTO emails (email)
VALUES ('example@student.com');
La query va a buon fine.
Esempio 3: Controllo di condizioni su più colonne
Le constraint CHECK possono controllare non solo una colonna, ma anche espressioni logiche che coinvolgono più colonne. Vediamo l’esempio della tabella employees, dove lo stipendio (salary) deve essere maggiore dei bonus (bonus):
CREATE TABLE employees (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
salary NUMERIC CHECK (salary > 0),
bonus NUMERIC CHECK (bonus >= 0),
CHECK (salary > bonus)
);
Ora, se qualcuno prova ad aggiungere un dipendente con bonus più alto dello stipendio, il database non lo permette:
INSERT INTO employees (name, salary, bonus)
VALUES ('Otto Lin', 3000, 4000);
Errore:
ERROR: new row for relation "employees" violates check constraint "employees_salary_bonus_check"
DETAIL: Failing row contains (1, Otto Lin, 3000, 4000).
Applicazioni pratiche
La constraint CHECK è utile quando la tua business logic è strettamente legata a limiti sui dati. Per esempio:
- E-commerce: vietare l’aggiunta di prodotti con prezzo negativo.
- Piattaforme educative: controllo dell’età dei partecipanti ai corsi.
- Sistemi medici: assicurarsi che la temperatura corporea del paziente sia nei limiti accettabili.
Questi controlli non sono solo un livello extra di sicurezza, ma fanno risparmiare tempo e nervi a sviluppatori e utenti.
Particolarità ed errori tipici
Quando lavori con CHECK, tieni a mente queste cose:
Le espressioni logiche in
CHECKdevono essere vere per tutte le righe della tabella. Se anche solo una riga viola la regola, prima di aggiungere la constraint devi sistemarla.Il controllo non viene eseguito se il valore inserito è
NULL. In altre parole,CHECK (age >= 18)non darà errore perage = NULL. Questo perché ogni espressione che contieneNULLdiventa automaticamente indefinita. Se vuoi vietareNULL, aggiungiNOT NULL.Condizioni complesse in
CHECKpossono rallentare l’inserimento e l’aggiornamento dei dati, soprattutto su tabelle grandi.
GO TO FULL VERSION