1. Cum Proiectăm o Bază de Date?

⚠️ Capcana începătorului: „Tabelul Universal” (De ce nu punem totul într-un singur tabel?)

Când primesc o problemă reală, mulți începători sunt tentați să creeze un singur tabel uriaș (similar unei foi Excel) în care adaugă toate coloanele posibile. În teoria bazelor de date, un astfel de tabel neîmpărțit generează redundanță masivă și trei tipuri grave de erori, numite anomalii:

❌ Un singur tabel gigant (Neproiectat)

  • Anomalie de modificare: Dacă un client își schimbă numărul de telefon și apare pe 20 de comenzi, trebuie să modificăm manual toate cele 20 de rânduri. Dacă uităm unul, baza de date devine inconsistentă.
  • Anomalie de ștergere: Dacă ștergem ultima comandă a unui produs, riscăm să pierdem complet și datele despre existența sau prețul acelui produs.
  • Anomalie de inserare: Nu putem adăuga un medic nou în baza de date până când acesta nu are cel puțin un pacient programat.

✅ Bază de date proiectată (Normalizată)

  • O tabelă = O singură entitate: Datele despre clienți stau în CLIENTI, produsele în PRODUSE, iar comenzile în COMENZI.
  • Fără informații repetate: Numărul de telefon al unui client se stochează într-un singur loc. Orice modificare se propagă instantaneu.
  • Valori atomice: În fiecare celulă a unui tabel stocăm o singură valoare (nu punem o listă de produse separate prin virgulă într-o singură căsuță).

Algoritmul de proiectare a unei baze de date (5 Pași)

Atunci când primești descrierea unei probleme din lumea reală, urmează această ordine logică pentru a stabili tabelele și câmpurile:

Pasul 1: Identifică Entitățile (Tabelele)

Citește enunțul și subliniază substantivele principale (obiecte, persoane, concepte sau evenimente) despre care trebuie să păstrăm mai multe informații.

Indiciu: Dacă o categorie are cel puțin 2-3 proprietăți proprii (ex: un Medic are nume, specializare, grad profesional), atunci devine tabelul MEDICI.

Pasul 2: Stabilește Atributele (Câmpurile)

Pentru fiecare tabel identificat, decide ce coloane îi aparțin în mod direct. Asigură-te că fiecare câmp conține o valoare atomică (indivizibilă) și are un tip de date clar (INT, VARCHAR, DECIMAL, DATE).

Regulă: Nu stoca în tabel câmpuri care se pot calcula ușor (de exemplu, stocăm Data_Nasterii, nu Varsta care se schimbă în fiecare an).

Pasul 3: Alege Cheile Primare (PK)

Fiecare tabel trebuie să aibă o coloană care identifică fără dubiu fiecare rând. Cel mai sigur este să definim o cheie primară numerică artificială (ex: ID_Client, ID_Produs).

De ce nu Nume ca PK? Două persoane diferite se pot numi „Popescu Andrei”. În schimb, ID_Client = 104 este garantat unic.

Pasul 4: Analizează Relațiile (1:1, 1:M, M:M)

Ia tabelele două câte două și pune întrebarea în ambele sensuri: „Un element din A se poate asocia cu mai multe din B? Dar unul din B cu mai multe din A?”

Aplicație: Dacă relația este 1:M, adaugă cheia primară din tabelul „1” ca Cheie Externă (FK) în tabelul „M”.

Pasul 5: Descompune Relațiile M:M

Ori de câte ori descoperi o relație Mulți-la-Mulți (M:M) între două tabele, creează obligatoriu un tabel de legătură (asociativ).

Atenție: Tabelul asociativ preia cele două Chei Externe (FK) și păstrează atributele acțiunii (ex: Cantitate, Data_Programarii, Nota_Obtinuta).

Verificarea alegerilor anterioare(Checklist)

Înainte să treci la implementarea schemei de BD, verifică următoarele trei condiții:

1. Niciun câmp nu conține liste de valori separate prin virgulă.
2. Datele de contact/denumirile nu se repetă inutil.
3. Orice cheie externă (FK) pointează spre o cheie primară (PK) existentă.

2. Atelier Interactiv: Selectarea Tabelelor și a Câmpurilor

Rezolvă cele 3 scenarii reale de mai jos. Pentru fiecare problemă, parcurge 2 etape de selecție ghidată:
Pasul 1: Selectează din oferta propusă tabelele necesare (maxim 3 tabele per problemă).
Pasul 2: După ce ai selectat corect tabelele, alege câmpurile (atributele + cheile PK/FK) specifice fiecărui tabel!

Exemplu Model de Gândire: Sistem de Bibliotecă

Cerință: Evidența cărților, a elevilor și a împrumuturilor.
• Relația dintre ELEV_CITITORI și CARTI este de tip Mulți-la-Mulți (M:M) (un elev împrumută mai multe cărți, o carte este împrumutată de mai mulți elevi).
• Rezolvare: 3 tabele — ELEV_CITITORI (PK: ID_Elev), CARTI (PK: ID_Carte) și tabelul asociativ IMPRUMUTURI (PK: ID_Imprumut, FK: ID_Elev, FK: ID_Carte, plus atributele Data_Imprumut, Data_Restituire).

📘 Problema 1: Catalog Școlar Electronic (Gestiune Note)

Scenariu: Un liceu dorește să proiecteze o bază de date simplă pentru a gestiona evidența elevilor, a materiilor de studiu și a notelor obținute de elevi la fiecare materie.

Etapa 1: Selectează tabelele necesare din oferta de mai jos:
Etapa 2: Selectează câmpurile potrivite pentru fiecare dintre cele 3 tabele:

Tabelul ELEVI (Alege câmpurile corecte):

Tabelul MATERII (Alege câmpurile corecte):

Tabelul NOTE (Tabel de legătură - Alege campurile corecte):

🏥 Problema 2: Cabinet Stomatologic (Programări)

Scenariu: Un cabinet medical dorește să păstreze evidența pacienților, a medicilor stomatologi și a programărilor efectuate de pacienți la medici.

Etapa 1: Selectează tabelele necesare din oferta de mai jos:
Etapa 2: Selectează câmpurile potrivite pentru fiecare dintre cele 3 tabele:

Tabelul PACIENTI (Alege câmpurile corecte):

Tabelul MEDICI (Alege câmpurile corecte):

Tabelul PROGRAMARI (Alege câmpurile corecte):

👟 Problema 3: Magazin Online de Încălțăminte

Scenariu: Un magazin online dorește o bază de date pentru a gestiona clienții înregistrați, produsele din stoc (pantofi/pantofi sport) și comenzile plasate de clienți.

Etapa 1: Selectează tabelele necesare din oferta de mai jos:
Etapa 2: Selectează câmpurile potrivite pentru fiecare dintre cele 3 tabele:

Tabelul CLIENTI (Alege câmpurile corecte):

Tabelul PRODUSE (Alege câmpurile corecte):

Tabelul COMENZI (Alege câmpurile corecte):

Scor Atelier Interactiv: 0 / 6 etape finalizate
Rezolvă cele 3 probleme interactive de proiectare!

3. Studiu de Caz: Service și Atelier de Biciclete

Să urmărim concret cum transformăm o evidență neorganizată într-o bază de date relațională corectă. Un atelier local de reparații biciclete ține evidența intervențiilor într-un singur tabel. Un client poate aduce în service una sau mai multe biciclete, fiecare bicicletă poate avea în timp mai multe intervenții (revizii/reparații), iar la o intervenție se pot folosi mai multe piese de schimb din magazie.

Pasul A: Cum arată tabelul GREȘIT (Neproiectat)?

Mai jos este modul în care proprietarul atelierului a încercat să noteze totul într-un singur tabel. Observă zonele marcate cu roșu (redundanță) și portocaliu (valori multiple în aceeași celulă):

Nr_Fisa Nume_Client Telefon_Client Model_Bicicleta Dimensiune_Roata Data_Service Piese_Inlocuite_Si_Cantitate Manopera_RON
1 Mureșan Dan 0740111222 Cube Aim SL 27.5 inch 2026-10-05 2x Cameră 27.5 valvă Schrader (AV), 1x Set plăcuțe frână 80.00
2 Popa Elena 0722333444 Merida Crossway 28 inch (700c) 2026-10-09 2x Anvelopă Continental 700x35c, 1x Lanț 9 viteze 100.00
3 Mureșan Dan 0740111222 Cube Aim SL 27.5 inch 2026-10-28 1x Cablu schimbător spate 45.00
Ce este greșit în tabelul de mai sus?
1. Datele clientului și ale bicicletei se repetă la fiecare vizită în service (rândurile 1 și 3).
2. Coloana Piese_Inlocuite_Si_Cantitate conține mai multe piese laolaltă sub formă de text. Este imposibil să calculăm automat în SQL câte camere cu valvă Schrader mai avem în stoc sau care este valoarea totală a pieselor vândute!

Pasul B: Proiectarea Corectă (Împărțirea în 5 Tabele Corelate)

Aplicând algoritmul în 5 pași, separăm informațiile pe entități distincte și legăm tabelele prin chei primare (PK) și externe (FK):

1. CLIENTI Tabel 1
  • ID_Client (PK) INT
  • Nume_Complet VARCHAR(60)
  • Telefon VARCHAR(15)
  • Email VARCHAR(60)
2. BICICLETE 1:M cu CLIENTI
  • ID_Bicicleta (PK) INT
  • Marca_Model VARCHAR(50)
  • Serie_Cadru VARCHAR(30)
  • Dimensiune_Roata VARCHAR(20)
  • ID_Client (FK) INT
3. INTERVENTII 1:M cu BICICLETE
  • ID_Interventie (PK) INT
  • Data_Primire DATE
  • Descriere_Defect VARCHAR(150)
  • Cost_Manopera DECIMAL(7,2)
  • ID_Bicicleta (FK) INT
4. PIESE_SCHIMB Catalog Piese
  • ID_Piesa (PK) INT
  • Denumire_Piesa VARCHAR(80)
  • Pret_Unitar_RON DECIMAL(7,2)
  • Stoc_Magazie INT
5. PIESE_DEVIZ Legătură M:M
  • ID_Linie (PK) INT
  • ID_Interventie (FK) INT
  • ID_Piesa (FK) INT
  • Cantitate INT

Explicația arhitecturii:
• Un client (CLIENTI) poate deține mai multe biciclete (BICICLETE) -> relație 1:M prin ID_Client (FK).
• O bicicletă (BICICLETE) poate avea în timp mai multe fișe de reparație (INTERVENTII) -> relație 1:M prin ID_Bicicleta (FK).
• La o intervenție se folosesc mai multe piese, iar un tip de piesă se folosește la mai multe intervenții -> relație M:M descompusă prin tabelul asociativ PIESE_DEVIZ, unde stocăm și Cantitatea montată.

4. Exersare Practică și Autoevaluare

Verifică-ți intuiția de arhitect de baze de date! Parcurge scenariile de mai jos:

Partea I: În ce tabel plasăm câmpul?

Pentru fiecare cerință de mai jos, alege tabelul corect în care trebuie creat câmpul menționat, astfel încât baza de date să nu aibă redundanțe:

1. Într-o bază de date cu CARTI, CITITORI și tabelul de legătură IMPRUMUTURI, în ce tabel plasăm câmpul Data_Restituirii?
2. Între tabelele DEPARTAMENTE (partea 1) și ANGAJATI (partea M), unde plasăm câmpul Salariu_Incadrare al unui angajat?
3. O școală are tabelele ELEVI, DISCIPLINE și NOTE. Unde plasăm câmpul Nr_Ore_Pe_Saptamana alocat unei materii?
4. Avem tabelele FACTURI, PRODUSE și LINII_FACTURA. Unde adăugăm câmpul Cantitate_Cumparata?
5. Între AUTOTURISME (1) și REVIZII_TEHNICE (M), unde adăugăm Cheia Externă pentru a lega cele două tabele?

Partea a II-a: Proiectare BD

Selectează varianta corectă pentru fiecare dintre cele 6 întrebări de mai jos:

1. În timpul proiectării tabelului ELEVI, un coleg propune coloana Limbi_Straine în care să se completeze valori de forma "Engleză, Franceză, Germană". Ce regulă de proiectare este încălcată?

A. Regula unicității cheii primare.
B. Regula atomicitații atributelor (stocarea mai multor valori în aceeași celulă).
C. Regula integrității referențiale.

2. Proiectăm baza de date a unui campionat de fotbal în care o echipă joacă mai multe meciuri, dar la fiecare MECI participă exact două echipe: o echipă gazdă și o echipă oaspete. Cum legăm tabelul MECIURI de tabelul ECHIPE?

A. Adăugăm în tabelul MECIURI două Chei Externe: ID_Echipa_Gazda (FK) și ID_Echipa_Oaspete (FK).
B. Adăugăm câmpul ID_Meci (FK) în tabelul ECHIPE.
C. Punem un singur câmp text Echipe_Participante în care scriem ambele nume.

3. De ce este recomandat să folosim un câmp numeric de tip ID_Client (INT) ca și Cheie Primară în tabelul CLIENTI, în locul câmpului Nume_Complet (VARCHAR)?

A. Deoarece limbajul SQL interzice folosirea tipului VARCHAR ca și cheie primară.
B. Deoarece două persoane pot avea același nume, iar căutarea și legăturile (JOIN) pe numere întregi sunt mai rapide și sigure.
C. Deoarece cheile de tip text limitează tabelul la maximum 100 de rânduri.

4. Într-o bază de date școlară, un elev poate împrumuta aceeași carte de la bibliotecă de mai multe ori în ani diferiți. În tabelul asociativ IMPRUMUTURI avem câmpurile ID_Elev (FK), ID_Carte (FK) și Data_Imprumut. Cum definim Cheia Primară a tabelului IMPRUMUTURI?

A. Setăm doar câmpul ID_Elev drept Cheie Primară.
B. Folosim exclusiv perechea (ID_Elev, ID_Carte) fără niciun alt câmp.
C. Adăugăm un câmp ID_Imprumut (PK) dedicat (sau formăm cheia compusă din ID_Elev + ID_Carte + Data_Imprumut).

5. Ce tip de date SQL este cel mai potrivit pentru stocarea câmpului Pret_Unitar al unui produs într-un magazin (ex: 149.99 RON)?

A. INT (număr întreg)
B. DECIMAL(8,2) (număr cu virgulă fixă și două zecimale exacte)
C. VARCHAR(20) (șir de caractere)

6. Dacă într-un singur tabel COMENZI_PRODUSE păstrăm atât produsele vândute, cât și datele furnizorului, iar la ștergerea ultimei comenzi a unui produs pierdem și numărul de telefon al furnizorului, cum se numește această problemă de proiectare?

A. Anomalie de ștergere (cauzată de lipsa separării entităților în tabele distincte).
B. Eroare de indexare binară.
C. Restricție de cheie externă.
Scor curent: 0 / 11 puncte
Rezolvă cele 5 decizii de plasare (Partea I) și cele 6 întrebări grilă (Partea a II-a)!