Salt la conținutul principal
Modulul 9 · Lecția 2 din 434/57 în curs~12 min
Lecții din modul (2/4)

Constrângeri multiple și la nivel de tabel

Asigurarea faptului că datele din baza de date sunt corecte la nivelul cel mai elementar ("integritatea datelor") este fundamentală. Dacă scrieți siguranță numai în aplicația Node.js, erorile ar putea cauza date inconsecvente în DB. Constrângerile la nivelul DDL sunt ultima linie de apărare impenetrabilă.

Principalele constrângeri

Pe lângă PRIMARY KEY (care face o coloană unică și NOT NULL) și clasicele NOT NULL și UNIQUE, există două categorii fundamentale pentru consistența logică a datelor:

1. CHEIE străină (integritate referenţială)

O constrângere REFERENCES asigură că un ID de legătură există într-adevăr în tabelul „părinte” către care indică. De exemplu, o comandă trebuie să fie legată de un client existent.

SQL
CREATE TABLE orders (
  id SERIAL PRIMARY KEY,
  customer_id INTEGER REFERENCES customers(id)
);

Ce face cheia externă?

  • Vă împiedică să introduceți un customer_id care nu există în customers.
  • Vă împiedică să DELETE (ștergerea) un client din customers dacă există comenzi care țin spre el (protejează împotriva înregistrărilor „orfane”).

De asemenea, putem decide ce ar trebui să se întâmple când „părintele” este șters:

SQL
customer_id INTEGER REFERENCES customers(id) ON DELETE CASCADE

Cu ON DELETE CASCADE, dacă ștergem clientul, Postgres va elimina automat toate orders conectate! (Folosiți cu mare precauție; în mod normal, setarea implicită care blochează operația este de preferat.)

2. VERIFICAȚI Constrângeri

O constrângere CHECK validează rândul testând o expresie booleană înainte de a continua salvarea.

SQL
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)
);

Prima CHECK este o constrângere de coloană (se referă doar la stipendio). A doua CHECK din partea de jos este o constrângere de tabel (poate încrucișa valori din mai multe coloane și trebuie declarată în partea de jos).

Dacă un INSERT sau UPDATE încearcă să salveze sfârșitul înainte de începere, Postgres îl va respinge cu o eroare!

Constrângeri de denumire

Este adesea o bună practică să acordați constrângerilor un nume explicit (folosind cuvântul cheie CONSTRAINT). În acest fel, când Postgres blochează o înregistrare, eroarea vă va spune, de exemplu, „constraint 'stipendio_positivo' încălcat”, ceea ce este mult mai clar pentru depanare!

SQL
CREATE TABLE prodotti (
  id SERIAL PRIMARY KEY,
  nome VARCHAR(50),
  CONSTRAINT nome_univoco UNIQUE(nome)
);

Încearcă

Exercițiu#sql.m9.l2.e1
Încercări: 0Se încarcă…

Creați un tabel „prenotazioni” cu id (SERIA PRIMARY KEY) și un „customer_id” (INTEGER). Utilizați CONSTRAINT fk_cliente FOREIGN KEY (customer_id) REFERENCES customers(id) pentru a da un nume explicit constrângerii Foreign Key. Faceți-o în partea de jos, ca o constrângere de masă.

Se încarcă editorul...
Afișează indiciu

Scrieți CONSTRAINT fk_cliente FOREIGN KEY (coloană_locală) REFERINȚE tabel_extern(col_externă)

Soluție disponibilă după 3 încercări

Constrângeri cu logică personalizată

Exercițiu#sql.m9.l2.e2
Încercări: 0Se încarcă…

Creați un tabel „eventi” cu id (SERIA PRIMARY KEY), posti_totali (INTEGER) și biglietti_venduti (INTEGER). Adăugați o constrângere de tabel numită „check_capienza” unde biglietti_venduti nu trebuie să fie niciodată mai mare decât posti_totali.

Se încarcă editorul...
Afișează indiciu

Adăugați constrângerea din partea de jos folosind CONSTRAINT check_capienza CHECK (expresie)

Soluție disponibilă după 3 încercări