5.3. restricţii
Tipurile de date limitează setul de date care pot fi stocate în tabel. Cu toate acestea, pentru multe aplicații, astfel de restricții sunt prea brute. De exemplu, o coloană care conține prețul unui produs ar trebui să ia doar valori pozitive. Dar nu există un astfel de tip de date standard. De asemenea, este posibil să doriți să limitați datele coloanelor la alte coloane sau rânduri. De exemplu, în tabelul cu informații despre produs ar trebui să existe o singură linie cu un anumit cod de produs.
Pentru a rezolva astfel de probleme, SQL vă permite să definiți constrângeri pentru coloane și tabele. Restricțiile vă permit să gestionați datele în tabele așa cum doriți. Dacă utilizatorul încearcă să stocheze o valoare în coloana care încalcă constrângerile, va apărea o eroare. Vor exista restricții, chiar dacă aceasta este valoarea implicită.
5.3.1. Limitări de verificare
Controlul restricțiilor este cel mai frecvent tip de constrângere. În definiția sa, puteți specifica că valoarea acestei coloane trebuie să satisfacă o expresie booleană (validarea adevărului). De exemplu, prețul bunurilor poate fi limitat la valori pozitive după cum urmează:
După cum puteți vedea, restricția este determinată după tipul de date, ca și valoarea implicită. Valorile implicite și restricțiile pot fi specificate în orice ordine. Verificarea restricțiilor constă în cuvântul cheie CHECK. urmată de o expresie în paranteze. Această expresie trebuie să includă o coloană pentru care este specificată constrângerea, altfel nu prea are sens.
De asemenea, puteți atribui un nume constrângerii. Acest lucru va îmbunătăți mesajele de eroare și vă va permite să vă referiți la această limitare când trebuie să o modificați. Puteți face așa:
Adică, pentru a crea o constrângere numită, scrieți cuvântul cheie CONSTRAINT. și apoi identificatorul și definiția restricției în sine. (Dacă nu definiți numele constrângerii în acest fel, sistemul va alege un nume pentru acesta.)
Verificarea constrângerii se poate referi și la mai multe coloane. De exemplu, dacă păstrați un preț regulat și un preț cu discount, puteți garanta că prețul de reducere va fi întotdeauna mai mic decât de obicei:
Primele două constrângeri sunt definite într-un mod similar, dar a treia o utilizează o nouă sintaxă. Nu este asociat cu o anumită coloană, ci este reprezentat de un element individual din listă. Definițiile coloanelor și astfel de definiții ale constrângerilor pot fi rearanjate în orice ordine.
Despre primele două limitări se poate spune că aceste constrângeri de coloană, în timp ce al treilea este o constrângere tabel, deoarece este scris separat de definițiile coloanelor. constrângeri de coloană pot fi, de asemenea, scris ca constrângeri de masă, în timp ce invers nu este întotdeauna posibil, deoarece aceasta implică faptul că o constrângere coloană se referă numai la coloana asociată. (. Deși Postgres Pro nu impune, ci pentru compatibilitatea cu alte sisteme de baze de date este cel mai bine să urmeze această regulă) rezultase exemplu poate fi rescris astfel:
Puteți atribui nume constrângerilor de tabelă în același mod ca constrângerile coloanelor:
Trebuie notat că verificarea constrângerilor este îndeplinită dacă expresia este adevărată sau NULL. Deoarece rezultatul multor expresii cu operanzii NULL este NULL, astfel de restricții nu vor împiedica scrierea NULL în coloanele asociate. Pentru a vă asigura că coloana nu conține o valoare NULL, puteți utiliza constrângerea NOT NULL descrisă în secțiunea următoare.
5.3.2. NU Restricții
Constrângerea NOT NULL indică pur și simplu faptul că coloana nu poate fi setată la NULL. Exemplu de sintaxă:
Constrângerea NOT NULL este întotdeauna scrisă ca o constrângere coloană și este echivalentă funcțional cu constrângerea CHECK (numele_conelei NU este NULL). dar în Postgres Pro constrângerea explicită NOT NULL funcționează mai eficient. Deși această înregistrare are un dezavantaj - nu puteți aloca un nume acestor restricții.
Firește, pentru o coloană, puteți defini mai multe constrângeri. Pentru aceasta, trebuie doar să fie indicate una după alta:
Ordinul de aici nu contează, nu corespunde neapărat ordinii de verificare a constrângerilor.
Pentru a limita NOT NULL există o constrângere inversă: NULL. Aceasta nu înseamnă că coloana trebuie să aibă o valoare NULL, care, desigur, ar fi inutilă. Esența lui este să specificați pur și simplu că coloana poate avea o valoare NULL (acesta este comportamentul implicit). Constrângerea NULL nu este în standardul SQL și nu ar trebui să fie utilizată în aplicații portabile. (Acesta a fost adăugat la Postgres Pro numai pentru compatibilitatea cu alte sisteme de baze de date.) Cu toate acestea, unii utilizatori ca să-l folosească, deoarece vă permite să comutați cu ușurință restricțiile în script. De exemplu, puteți începe cu:
și apoi introduceți cuvântul cheie NU. acolo unde este necesar.
La proiectarea bazelor de date cel mai adesea cele mai multe coloane ar trebui să fie etichetate NOT NULL.
5.3.3. Limitări ale unicității
Constrângerile unice asigură faptul că datele dintr-o anumită coloană sau grup de coloane sunt unice printre toate rândurile din tabel. Restricția este scrisă ca:
sub forma unei constrângeri în coloană și astfel:
sub forma unei constrângeri de masă.
Pentru a defini o constrângere unică pentru un grup de coloane, scrieți-o ca o constrângere de tabelă afișând numele coloanelor separate prin virgule:
O astfel de restricție indică faptul că combinația dintre valorile listate coloanele trebuie să fie unice pe masă, în timp ce valorile fiecărei coloane separat nu ar trebui să fie (și, în general, nu vor) să fie unic.
Puteți atribui o constrângere unică numelui în mod obișnuit:
Când adăugați o constrângere unică, este creat automat un index B-tree unic pentru coloana sau grupul de coloane listate în constrângere. Condiția de unicitate, care se aplică numai anumitor linii, nu poate fi scrisă ca o constrângere unică, însă puteți seta o astfel de condiție creând un indice parțial unic.
În general, constrângerea de unicitate este încălcată dacă există mai multe rânduri în tabel care au aceleași valori ale tuturor coloanelor incluse în constrângere. Cu toate acestea, două valori NULL nu sunt niciodată considerate egale în comparație. Aceasta înseamnă că, chiar dacă există o constrângere unică în tabel, puteți salva rânduri cu valori duplicate dacă acestea conțin NULL într-una sau mai multe coloane de constrângere. Acest comportament este conform cu standardul SQL, dar am auzit despre SGBD care se comportă diferit. Țineți cont de această caracteristică atunci când dezvoltați aplicații portabile.
5.3.4. Cheile primare
O constrângere de cheie primară înseamnă că grupul de coloane sau coloane care o formează poate fi un identificator de rând unic în tabel. Acest lucru necesită ca valorile să fie unice și diferite de NULL. Astfel, tabelele cu următoarele două definiții vor avea aceleași date:
Tastele primare pot include mai multe coloane; sintaxa este similară înregistrării constrângerilor de unicitate:
Atunci când adăugați o cheie primară creează automat un index-B-arbore unic pentru un grup de coloane sau o coloană, listate în cheia primară, iar coloanele de date sunt marcate ca NOT NULL.
O tabelă poate avea maximum o cheie primară. (Constrângeri unice și limitări NOT NULL, care sunt chei primare aproape echivalente funcțional, poate fi orice, dar atribuie constrângere cheie primară poate fi doar unul.) Bazele de date Teoria relațională a spus cheia primară trebuie să fie în fiecare tabel. Postgres Pro nu are o cerință atât de strictă, dar este de obicei mai bine să o urmezi.
Cheile primare sunt utile atât pentru documentația, cât și pentru aplicațiile client. De exemplu, o aplicație grafică cu capacitățile de editare a conținutului unui tabel poate necesita cunoașterea cheii primare a tabelului pentru identificarea unică a rândurilor sale. Cheile principale găsesc, de asemenea, alte aplicații în DBMS; în particular, cheia primară din tabel definește coloanele țintă implicite pentru cheile terță parte care fac trimitere la acest tabel.
5.3.5. Cheile externe
Constrângerea cheii străine specifică faptul că valorile coloanei (sau grupului de coloane) trebuie să se potrivească cu valorile dintr-un rând din celălalt tabel. Aceasta se numește integritatea referențială a două tabele conectate.
Să aveți deja o masă de produse, pe care am folosit-o în mod repetat înainte:
Să presupunem că aveți un tabel cu comenzi pentru aceste produse. Vrem ca tabelul de comenzi să conțină doar comenzi pentru produse cu adevărat existente. Prin urmare, definim în ea o constrângere cheie străină referitoare la tabelul de produse:
Cu această restricție, creați o comandă cu valoarea product_no. care nu este prezent în tabelul de produse (și nu este egal cu NULL), va fi imposibil.
Într-o astfel de schemă, tabelul de comenzi se numește o tabelă slave, iar produsele se numesc tabelul principal. În consecință, coloanele sunt, de asemenea, numite coloane subordonate și principale (sau de referință și țintă).
Comanda anterioară poate fi redusă după cum urmează:
adică, dacă omiteți lista de coloane, cheia externă va fi asociată implicit cu cheia primară a tabelului principal.
O cheie străină se poate referi și la un grup de coloane. În acest caz, ar trebui să fie scris sub forma unei constrângeri normale de masă. De exemplu:
Bineînțeles, numărul și tipurile de coloane din constrângere trebuie să se potrivească numărului și tipurilor coloanelor țintă.
Puteți să atribuiți un nume constrângerii cheii străine în mod standard.
Un tabel poate conține mai multe constrângeri cheie străine. Acest lucru este util pentru conectarea tabelelor la multi-la-mulți. Să presupunem că aveți tabele de produse și comenzi, dar doriți ca o comandă să conțină mai multe produse (ceea ce nu este posibil în schema anterioară). Pentru aceasta puteți utiliza această schemă:
Rețineți că în ultimul tabel, cheia primară acoperă cheile externe.
Știm că cheile străine interzic crearea de comenzi care nu sunt legate de niciun produs. Dar ce se întâmplă dacă după ce ați creat comenzi cu un anumit produs, dorim să îl ștergem? SQL va face față acestei situații. Intuiția sugerează următoarele comportamente:
Nu permiteți scoaterea produsuluiPentru a ilustra, să pună în aplicare următorul comportament în exemplul de mai sus: dacă încercați să ștergeți un produs care se face referire ordinele (prin order_items de masă), nu permitem această operație. Dacă cineva încearcă să ștergă o comandă, atunci conținutul acesteia va fi șters:
Restricțiile și restricțiile în cascadă sunt cele două variante cele mai comune. RESTRICT previne eliminarea unui șir conectat. FĂRĂ ACȚIUNE înseamnă că dacă liniile dependente continuă să existe la verificarea unei constrângeri, apare o eroare (acesta este comportamentul implicit). (Diferența principală dintre aceste două opțiuni este faptul că nici o acțiune permite verificarea să întârzie procesul de tranzacție și restricționând - nr.) CASCADE specifică faptul că ștergerea rândurilor aferente depind de acestea vor fi șterse automat. Există încă două opțiuni: SET NULL și SET DEFAULT. Când ștergeți rândurile asociate, acestea atribuie valorile NULL sau valorile implicite la coloanele dependente din tabelul de subordonare. Rețineți că acest lucru nu va fi un motiv pentru încălcarea restricțiilor. De exemplu, dacă acțiunea este setată la SET DEFAULT. Cu toate acestea, valoarea implicită nu satisface constrângerea cheii străine, operația va eșua.
Similar cu ON DELETE, ON UPDATE există. care este declanșată când se modifică coloana specificată. Acțiunile posibile sunt aceleași, iar CASCADE în acest caz înseamnă că valorile modificate ale coloanelor legate vor fi copiate în rândurile dependente.
5.3.6. Limitările-excludere
Limitările-excludere se asigură că, atunci când se compară oricare două dintre rânduri sau coloane folosind expresiile operatori date, cel puțin unul dintre aceste comparații sau NULL return false. Este scris astfel: