Baze de date – noțiuni fundamentale
Prezentarea modelului relațional de baze de date și operații elementare.
Bacalaureat
Modelul relațional: tabele, câmpuri, înregistrări
O bază de date este o colecție organizată de date persistente, gestionată de un SGBD (Sistem de Gestiune a Bazelor de Date) — programul care asigură stocarea, interogarea, integritatea și accesul concurent la date. Distincția bază de date / SGBD e prima întrebare de teorie: baza de date sunt datele, SGBD-ul este software-ul care le administrează (MySQL, PostgreSQL, Oracle).
În modelul relațional, datele sunt organizate în tabele (relații). Vocabularul, cu echivalențele care se cer:
- tabelul (relația) — o mulțime de date despre același tip de entitate (Elevi, Carti);
- câmpul (atributul, coloana) — o proprietate a entității (nume, medie); fiecare câmp are un tip de date (numeric, șir de caractere, dată calendaristică);
- înregistrarea (tuplul, linia, rândul) — datele complete ale unei singure entități concrete.
Reguli structurale ale modelului: fiecare celulă conține o valoare atomică (nu liste de valori), ordinea liniilor și a coloanelor nu contează logic, iar două înregistrări complet identice nu ar trebui să existe — de aici nevoia de chei.
Confuzia frecventă la început: tabelul NU e un fișier Excel — SGBD-ul impune tipuri, restricții de integritate și legături între tabele, exact componentele care lipsesc unei foi de calcul. Valorile absente se reprezintă prin NULL, un marcaj special care înseamnă „necunoscut”, diferit de 0 și de șirul vid.
Chei primare și chei externe
Cheia primară (primary key) este câmpul sau grupul de câmpuri care identifică unic fiecare înregistrare din tabel. Proprietățile ei, cerute exact așa:
- unicitate — două înregistrări nu pot avea aceeași valoare a cheii;
- nu admite NULL — fiecare înregistrare trebuie identificabilă;
- este minimală — niciun câmp al ei nu poate fi eliminat fără pierderea unicității.
Exemplu de judecată cerut în subiecte: în tabelul Elevi, CNP-ul poate fi cheie primară; numele nu poate (se repetă); adesea se adaugă un câmp artificial id numeric. Un tabel poate avea mai multe câmpuri candidate la unicitate (chei candidate), dintre care una se alege cheie primară.
Cheia externă (foreign key) este un câmp dintr-un tabel care referă cheia primară a altui tabel, creând legătura dintre ele. În tabelul Imprumuturi, câmpul id_elev este cheie externă spre Elevi.id — așa știe baza de date cine a împrumutat ce.
Cheia externă impune integritatea referențială: nu poți insera un împrumut cu un id_elev care nu există în Elevi și nu poți șterge un elev cât timp are împrumuturi care îl referă (decât dacă ștergerea se propagă explicit). Capcana de grilă: cheia externă poate avea valori care se repetă (un elev are multe împrumuturi) și, spre deosebire de cheia primară, poate fi NULL dacă legătura e opțională — cine îi atribuie automat proprietățile cheii primare pierde punctul.
Relații între tabele: 1-1, 1-n, m-n
Legăturile dintre tabele se clasifică după câte înregistrări dintr-un tabel corespund unei înregistrări din celălalt:
- 1-1 (unu la unu): unei înregistrări din A îi corespunde cel mult una din B și reciproc — elev și dosarul său medical. Se implementează punând în unul dintre tabele o cheie externă unică spre celălalt; relativ rară, folosită pentru separarea datelor sensibile sau rar accesate.
- 1-n (unu la mulți): unei înregistrări din A îi corespund oricâte din B, dar fiecare înregistrare din B ține de exact una din A — o clasă are mulți elevi, un elev e într-o singură clasă. Implementare: cheia externă stă întotdeauna în tabelul de pe partea „mulți” (Elevi primește id_clasa). Este de departe cea mai des întâlnită relație.
- m-n (mulți la mulți): elevi și opționale — un elev urmează mai multe opționale, un opțional are mai mulți elevi. Modelul relațional nu poate exprima direct m-n: se introduce un tabel asociativ (de legătură) — Inscrieri(id_elev, id_optional) — care sparge relația m-n în două relații 1-n. Perechea celor două chei externe formează de regulă cheia primară compusă a tabelului asociativ.
Greșeala care pierde cele mai multe puncte la proiectare: plasarea cheii externe pe partea greșită a relației 1-n (id_elev în Clase ar însemna o clasă cu un singur elev) sau tentativa de a stoca liste de id-uri într-un singur câmp — ambele încalcă chiar fundamentele modelului.
Normalizarea: eliminarea redundanței
Normalizarea este procesul de organizare a tabelelor astfel încât fiecare fapt să fie memorat o singură dată. Motivația se formulează prin anomalii — și ele se cer la examen cu nume cu tot:
- anomalia de actualizare: dacă adresa unei edituri apare în 200 de rânduri de cărți, schimbarea ei cere 200 de modificări, iar una ratată lasă date inconsistente;
- anomalia de inserare: nu poți înregistra o editură nouă până nu ai o carte de la ea;
- anomalia de ștergere: ștergând ultima carte a unei edituri, pierzi și datele editurii.
Formele normale, la nivelul cerut de programă:
- FN1 (prima formă normală): toate valorile sunt atomice — niciun câmp nu conține liste (un câmp telefoane cu trei numere separate prin virgulă încalcă FN1);
- FN2: FN1 + fiecare câmp nesecheie depinde de întreaga cheie primară, nu doar de o parte a ei (relevant la chei compuse);
- FN3: FN2 + niciun câmp nu depinde de alt câmp nesecheie (dependență tranzitivă) — dacă în Elevi ții id_clasa și diriginte, dirigintele depinde de clasă, nu de elev, deci pleacă în tabelul Clase.
Rezolvarea standard a fiecărei încălcări este aceeași: descompunerea tabelului în tabele mai mici legate prin chei externe. Nuanța matură, bună de menționat: normalizarea maximă nu e mereu ținta practică — mai multe tabele înseamnă mai multe join-uri la interogare; programa cere însă recunoașterea încălcărilor și descompunerea corectă până la FN3.
Interogarea datelor: SELECT, WHERE, ORDER BY
SQL (Structured Query Language) este limbajul standard al bazelor de date relaționale. Interogarea fundamentală:
- `SELECT nume, medie FROM elevi WHERE medie >= 9 ORDER BY medie DESC;`
cu rolurile: SELECT alege coloanele, FROM indică tabelul, WHERE filtrează liniile, ORDER BY sortează rezultatul (ASC implicit crescător, DESC descrescător). `SELECT *` returnează toate coloanele. SELECT DISTINCT elimină duplicatele din rezultat.
Condițiile din WHERE folosesc operatorii de comparație (=, <>, <, <=, >, >=), conectorii AND, OR, NOT și construcțiile speciale:
- BETWEEN a AND b — interval închis (include capetele);
- IN (lista) — apartenența la o mulțime de valori;
- LIKE cu metacaracterele % (orice șir, inclusiv vid) și _ (exact un caracter): `nume LIKE „Po%”` — nume care încep cu Po;
- IS NULL / IS NOT NULL — singurul mod corect de a testa valorile absente.
Aici stă capcana cotată cel mai sus la acest capitol: `câmp = NULL` nu funcționează — orice comparație obișnuită cu NULL are rezultat necunoscut, deci linia nu trece filtrul; testul corect este exclusiv IS NULL.
A doua confuzie frecventă: ordinea clauzelor este fixă — SELECT, FROM, WHERE, ORDER BY; un WHERE plasat după ORDER BY este eroare de sintaxă, iar filtrarea (WHERE, pe linii) nu trebuie confundată cu proiecția (SELECT, pe coloane).
Modificarea datelor: INSERT, UPDATE, DELETE
Cele trei comenzi care schimbă conținutul tabelelor:
- INSERT adaugă înregistrări: `INSERT INTO elevi (nume, medie) VALUES („Popescu”, 9.50);` — coloanele nemenționate primesc NULL sau valoarea implicită; inserarea trebuie să respecte restricțiile (cheie primară unică, chei externe existente, NOT NULL);
- UPDATE modifică înregistrări existente: `UPDATE elevi SET medie = 10 WHERE id = 7;` — SET spune ce se schimbă, WHERE spune la cine;
- DELETE șterge înregistrări: `DELETE FROM elevi WHERE medie < 5;` — șterge linii întregi, nu valori din câmpuri.
Avertismentul care trebuie să devină reflex, pentru examen și pentru viață: UPDATE sau DELETE fără clauza WHERE se aplică TUTUROR înregistrărilor din tabel. `DELETE FROM elevi;` golește complet tabelul — fără vreo confirmare. La subiecte, lipsa sau formularea greșită a WHERE-ului este exact ce diferențiază răspunsul corect de dezastru.
Distincții de vocabular care apar în grile:
- DELETE șterge date (înregistrări), dar tabelul continuă să existe, chiar gol; ștergerea structurii tabelului este DROP TABLE — altă categorie de comenzi (DDL, limbajul de definire), față de INSERT/UPDATE/DELETE care sunt DML (limbajul de manipulare);
- INSERT adaugă linii noi, UPDATE modifică linii existente — a folosi INSERT ca să „schimbi” media unui elev creează o a doua înregistrare (sau eșuează pe cheia primară), nu o corectează pe prima.
Integritatea referențială supraveghează tot: ștergerea unui elev cu împrumuturi active este refuzată de SGBD dacă legătura nu prevede propagarea ștergerii.
De reținut
- bază de date
- colecție organizată și persistentă de date, structurată în modelul relațional sub formă de tabele legate între ele
- SGBD
- sistemul de gestiune a bazelor de date — software-ul care asigură stocarea, interogarea, integritatea și accesul concurent la datele bazei (exemple: MySQL, PostgreSQL, Oracle)
- înregistrare (tuplu)
- o linie a unui tabel, conținând datele complete ale unei singure entități; câmpul (atributul) este o coloană, o proprietate a entității
- cheie primară
- câmpul sau grupul minimal de câmpuri care identifică unic fiecare înregistrare a tabelului; nu admite valori duplicate și nici NULL
- cheie externă
- câmp care referă cheia primară a altui tabel, realizând legătura dintre tabele; valorile ei se pot repeta și pot fi NULL dacă legătura este opțională
- integritate referențială
- regula conform căreia orice valoare a unei chei externe trebuie să existe drept cheie primară în tabelul referit; blochează inserările orfane și ștergerile care ar lăsa referințe invalide
- relație 1-n
- legătura în care unei înregistrări dintr-un tabel îi corespund oricâte înregistrări din celălalt; cheia externă se plasează întotdeauna în tabelul de pe partea mulți
- tabel asociativ
- tabel de legătură care implementează o relație m-n prin două chei externe, descompunând-o în două relații 1-n; perechea cheilor formează de regulă cheia primară compusă
- normalizare
- organizarea tabelelor astfel încât fiecare fapt să fie memorat o singură dată, eliminând redundanța și anomaliile de actualizare, inserare și ștergere prin descompunere în tabele legate
- NULL
- marcaj special pentru valoare absentă sau necunoscută, diferit de 0 și de șirul vid; se testează exclusiv cu IS NULL, orice comparație obișnuită cu NULL fiind necunoscută
Greșeli frecvente
Greșit: Cheia externă ar avea aceleași proprietăți ca cheia primară: valori unice și fără NULL
Corect: Cheia externă se poate repeta (un elev are multe împrumuturi) și poate fi NULL la legături opționale; unicitatea și interdicția NULL sunt proprietățile cheii primare
Greșit: O relație m-n s-ar implementa punând o cheie externă în fiecare dintre cele două tabele
Corect: Relația m-n cere un al treilea tabel, asociativ, cu două chei externe; o cheie externă simplă în oricare tabel ar limita relația la 1-n
Greșit: Valorile NULL s-ar filtra cu WHERE camp = NULL
Corect: Orice comparație cu NULL are rezultat necunoscut, deci nicio linie nu trece filtrul; testul corect este WHERE camp IS NULL, respectiv IS NOT NULL
Greșit: UPDATE sau DELETE fără WHERE ar afecta doar prima înregistrare
Corect: Fără WHERE, comanda se aplică tuturor înregistrărilor tabelului: DELETE FROM elevi; golește complet tabelul, iar UPDATE fără WHERE rescrie fiecare linie
Greșit: DELETE FROM tabel ar șterge și tabelul din baza de date
Corect: DELETE elimină doar înregistrările — tabelul rămâne, gol, cu structura intactă; structura se șterge cu DROP TABLE, comandă din DDL, nu din DML
Test — 6 întrebări ca la examen
1. Într-un tabel al modelului relațional, o înregistrare reprezintă:
- o proprietate a entității, cum ar fi numele
- datele complete ale unei singure entități concrete — o linie a tabelului
- tipul de date al unei coloane
- legătura tabelului cu alt tabel
Vezi răspunsul
datele complete ale unei singure entități concrete — o linie a tabelului. Înregistrarea (tuplul) este linia: toate valorile care descriu o entitate concretă. Prima variantă definește câmpul (coloana) — perechea de termeni pe care grilele o inversează sistematic; tipul de date și legăturile sunt noțiuni separate.
2. În tabelul Elevi(id, cnp, nume, medie), pot fi chei primare:
- nume, pentru că fiecare elev are un nume
- medie, pentru că este numerică
- id sau cnp, fiecare identificând unic un elev
- doar perechea (nume, medie), luată împreună
Vezi răspunsul
id sau cnp, fiecare identificând unic un elev. Atât id cât și cnp au valori unice și nenule, deci fiecare este cheie candidată; una se alege cheie primară. Numele se repetă (doi Popescu), media cu atât mai mult — iar faptul că un câmp e numeric nu îi dă nicio calitate de cheie; perechea nume+medie nu garantează nici ea unicitatea.
3. Într-o bibliotecă, o carte poate fi împrumutată de mai mulți elevi de-a lungul timpului, iar un elev împrumută mai multe cărți. Relația Elevi–Carti se implementează corect prin:
- o cheie externă id_carte adăugată în tabelul Elevi
- o cheie externă id_elev adăugată în tabelul Carti
- un tabel asociativ Imprumuturi cu cheile externe id_elev și id_carte
- un câmp în Elevi care memorează lista id-urilor cărților împrumutate
Vezi răspunsul
un tabel asociativ Imprumuturi cu cheile externe id_elev și id_carte. Relația este m-n și cere obligatoriu tabelul de legătură cu două chei externe. O cheie externă simplă în oricare tabel ar permite doar 1-n (varianta b ar însemna că o carte a fost împrumutată de un singur elev), iar lista de id-uri într-un câmp încalcă atomicitatea — prima formă normală.
4. Tabelul Elevi conține câmpurile id_clasa și diriginte, iar dirigintele este determinat de clasă, nu de elev. Situația încalcă:
- prima formă normală, pentru că dirigintele nu este valoare atomică
- a treia formă normală, existând o dependență tranzitivă printr-un câmp nesecheie
- integritatea referențială
- nicio regulă — datele sunt doar mai ușor de citit
Vezi răspunsul
a treia formă normală, existând o dependență tranzitivă printr-un câmp nesecheie. Dirigintele depinde de id_clasa, care nu e cheia tabelului — dependență tranzitivă, exact ce interzice FN3; corectarea mută dirigintele în tabelul Clase. Numele dirigintelui este o valoare atomică, deci FN1 nu e problema, iar integritatea referențială privește existența valorilor referite, nu dependențele.
5. Care interogare returnează numele elevilor fără medie înregistrată?
- SELECT nume FROM elevi WHERE medie = NULL;
- SELECT nume FROM elevi WHERE medie = 0;
- SELECT nume FROM elevi WHERE medie IS NULL;
- SELECT nume FROM elevi ORDER BY medie;
Vezi răspunsul
SELECT nume FROM elevi WHERE medie IS NULL;. Valoarea absentă se testează exclusiv cu IS NULL. Prima variantă e capcana premiată: sintaxa pare naturală, dar comparația cu NULL are rezultat necunoscut și nu întoarce nicio linie; media 0 este o valoare existentă, alt lucru decât lipsa valorii, iar ORDER BY doar sortează, nu filtrează.
6. Ce efect are comanda UPDATE elevi SET medie = 10; (fără clauza WHERE)?
- modifică media primei înregistrări din tabel
- produce eroare de sintaxă, WHERE fiind obligatoriu
- setează media 10 pentru toate înregistrările tabelului
- creează o înregistrare nouă cu media 10
Vezi răspunsul
setează media 10 pentru toate înregistrările tabelului. WHERE este opțional, iar absența lui înseamnă că modificarea se aplică fiecărei linii — toți elevii primesc media 10, fără avertisment. Prima variantă exprimă exact intuiția greșită care face comanda periculoasă; crearea de înregistrări noi este treaba lui INSERT, nu a lui UPDATE.
Deschide varianta interactivă — cu AI care îți explică