Invatare Atomica

Baze de date relationale si SQL: structura, interogari, operatii

Progres lectie:
0%
🎯

Obiectivul lectiei

Vei consolida modelul relational al bazelor de date si comenzile SQL fundamentale (SELECT, INSERT, UPDATE, DELETE, JOIN) pentru a interoga si manipula date organizate in tabele.

Dupa aceasta lectie vei putea:

  • Sa identifici componentele unui model relational (tabele, coloane, chei primare, chei straine)
  • Sa scrii interogari SELECT cu filtrare WHERE, ordonare ORDER BY si grupare GROUP BY
  • Sa folosesti JOIN pentru a combina date din mai multe tabele
  • Sa aplici INSERT, UPDATE si DELETE pentru modificarea datelor
  • Sa calculezi agregari cu COUNT, SUM, AVG, MIN, MAX
  • Sa descrii normalizarea (1NF, 2NF, 3NF) si sa identifici dependente functionale

Incearca singur!

Provocare:

Ai tabelul Elevi(id, nume, clasa, medie). Scrie o interogare SQL care returneaza numele si media elevilor din clasa '12A' cu media mai mare decat 8, ordonati descrescator dupa medie.

💡 Ai nevoie de un indiciu?

Structura generala: SELECT col1, col2 FROM tabel WHERE conditie ORDER BY col DESC;

Raspuns: SELECT nume, medie FROM Elevi WHERE clasa = '12A' AND medie > 8 ORDER BY medie DESC;

Nota: ORDER BY medie DESC sorteaza de la cea mai mare la cea mai mica medie.

1

1. Modelul relational: tabele, chei, relatii

O baza de date relationala organizeaza datele in tabele. Fiecare tabela are o cheie primara (PK) care identifica unic fiecare rand. Relatiile intre tabele sunt exprimate prin chei straine (FK).
-- Creare tabele cu PK si FK
CREATE TABLE Clase (
    id_clasa INTEGER PRIMARY KEY,
    denumire TEXT NOT NULL
);
CREATE TABLE Elevi (
    id_elev   INTEGER PRIMARY KEY,
    nume      TEXT    NOT NULL,
    clasa     TEXT,
    medie     REAL,
    id_clasa  INTEGER REFERENCES Clase(id_clasa)
);
CREATE TABLE Note (
    id_elev    INTEGER REFERENCES Elevi(id_elev),
    id_materie INTEGER,
    nota       INTEGER,
    PRIMARY KEY (id_elev, id_materie)  -- PK compusa
);
Concepte cheie:

PK (Primary Key): identifica unic fiecare rand; nu poate fi NULL, nu poate contine duplicate.

FK (Foreign Key): refera PK-ul altei tabele; asigura integritatea referentiala.

PK compusa: (id_elev, id_materie) impreuna identifica unic fiecare nota.

2

2. SELECT: filtrare, sortare, grupare

SELECT este comanda principala de interogare. Ordinea obligatorie a clauzelor: SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY → LIMIT. Functii de agregare: COUNT, SUM, AVG, MIN, MAX.
Interogari verificate (SQLite Python):
-- 1. Elevi din 12A cu medie > 8, descrescator:
SELECT nume, medie
FROM Elevi
WHERE clasa = '12A' AND medie > 8
ORDER BY medie DESC;

-- 2. Media pe clase cu HAVING:
SELECT clasa, AVG(medie) AS medie_clasa, COUNT(*) AS nr_elevi
FROM Elevi
GROUP BY clasa
HAVING AVG(medie) > 8;
Output real (rulat cu python sqlite3):
-- Interogare 1 (12A, medie>8, DESC):
Ana Popescu  | 9.50
Maria Popa   | 8.20

-- Interogare 2 (HAVING AVG>8):
12A | medie_clasa=8.40 | nr_elevi=3
12B | medie_clasa=8.90 | nr_elevi=2
3

3. JOIN: combinarea datelor din mai multe tabele

JOIN combina randuri din doua sau mai multe tabele pe baza conditiei PK = FK. INNER JOIN: returneaza doar randurile cu corespondent in ambele tabele (intersectie). LEFT JOIN: returneaza toate randurile din tabela stanga + NULL acolo unde nu exista corespondent.
INNER JOIN vs LEFT JOIN (output real):
-- INNER JOIN: doar elevii cu clasa existenta in Clase
SELECT e.nume, c.denumire
FROM Elevi e INNER JOIN Clase c ON e.id_clasa = c.id_clasa;
-- Output: Ana-12A | Ion-12B  (Ioana fara clasa - LIPSA)

-- LEFT JOIN: toti elevii, NULL daca clasa nu exista
SELECT e.nume, c.denumire
FROM Elevi e LEFT JOIN Clase c ON e.id_clasa = c.id_clasa;
-- Output: Ana-12A | Ion-12B | Ioana-NULL

-- JOIN pe 3 tabele (note >= 9):
SELECT e.nume, m.denumire, n.nota
FROM Elevi e
JOIN Note n ON e.id_elev = n.id_elev
JOIN Materii m ON n.id_materie = m.id_materie
WHERE n.nota >= 9;
-- Output: Ana-Informatica-10 | Ana-Matematica-9
4

4. Manipularea datelor: INSERT, UPDATE, DELETE

Comenzile DML (Data Manipulation Language) modifica datele: INSERT adauga randuri noi, UPDATE modifica date existente, DELETE sterge randuri. Intotdeauna foloseste WHERE la UPDATE si DELETE pentru a evita modificarea tuturor randurilor!
-- INSERT: adauga un elev nou
INSERT INTO Elevi (id_elev, nume, clasa, medie)
VALUES (6, 'Elena Mihai', '12A', 8.75);

-- UPDATE: modifica media unui elev specific (WHERE obligatoriu!)
UPDATE Elevi SET medie = 9.00 WHERE id_elev = 2;

-- DELETE: sterge un elev specific
DELETE FROM Elevi WHERE id_elev = 5;

-- PERICOL: fara WHERE afecteaza TOATE randurile!
-- UPDATE Elevi SET medie = 10;  <-- NU face asta!
Output real (rulat cu python sqlite3):
# Inainte UPDATE: Ion Ionescu | medie=7.80
# Dupa UPDATE id_elev=2: Ion Ionescu | medie=9.00

# INSERT verificat (id=6):
# 6 | Elena Mihai | 12A | 8.75
5

5. Subinterogari (subqueries)

O subinterogare (subquery) este un SELECT plasat in interiorul altui SELECT, WHERE, HAVING sau FROM. Permite interogari complexe fara rezultate intermediare. Operatori: = (o valoare), IN (lista de valori), EXISTS (existenta).
-- Elevii cu media PESTE media generala:
SELECT nume, medie FROM Elevi
WHERE medie > (SELECT AVG(medie) FROM Elevi);

-- Elevii care au nota la Informatica (IN + subquery):
SELECT nume FROM Elevi WHERE id_elev IN (
    SELECT id_elev FROM Note
    WHERE id_materie = (
        SELECT id_materie FROM Materii
        WHERE denumire = 'Informatica'
    )
);
Output real (rulat cu python sqlite3):
# Media generala: 8.42
# Elevi cu medie > 8.42:
Ana Popescu  | 9.50
Dan Radu     | 9.10

# Elevi cu nota la Informatica:
Ana Popescu
Dan Radu
6

6. Normalizare: 1NF, 2NF, 3NF

Normalizarea este procesul de proiectare a bazei de date pentru a elimina redundanta si anomaliile de actualizare. Se aplica in trepte: 1NF → 2NF → 3NF.
Treptele normalizarii (cu exemple concrete):
# NENORMALIZAT (incalca 1NF): valori ne-atomice
# id | elev | note       | clasa
#  1 | Ana  | 9, 10, 8   | 12A   <-- lista in celula!

# Dupa 1NF: valori atomice, PK compusa
# Note(id_elev, id_materie, nota)  PK=(id_elev, id_materie)

# Incalcare 2NF: Elevi(id_elev, id_materie, nota, NUME_ELEV)
# nume_elev depinde DOAR de id_elev (nu de intreaga PK)
# Solutie 2NF: Elevi(id_elev, nume) + Note(id_elev, id_materie, nota)

# Incalcare 3NF: Elevi(id_elev, nume, id_clasa, DENUMIRE_CLASA)
# denumire_clasa depinde tranzitiv: id_elev->id_clasa->denumire_clasa
# Solutie 3NF: Elevi(id_elev, nume, id_clasa) + Clase(id_clasa, denumire)
Rezumat forme normale:
1NF: valori atomice + fara grupuri repetitive de coloane
2NF: 1NF + fiecare atribut non-cheie depinde de INTREAGA cheie primara
3NF: 2NF + nicio dependenta tranzitiva intre atribute non-cheie

Exercitii practice

Exercitiul 1 (Nivel minim) — SELECT de baza

Scrie un SELECT care afiseaza numele si media tuturor elevilor cu media peste 7, ordonati alfabetic dupa nume. Tabel: Elevi(id_elev, nume, clasa, medie).

Exercitiul 2 (Nivel standard) — JOIN si agregari

Scrie o interogare care afiseaza numarul de elevi per clasa si media clasei, doar pentru clasele cu cel putin 3 elevi. Foloseste GROUP BY si HAVING.

Exercitiul 3 (Nivel performanta) — Normalizare + subinterogari

Identifica ce forma normala incalca aceasta tabela si propune solutia: Catalog(id_elev, nume_elev, id_materie, denumire_materie, nota). Scrie si o subinterogare care gaseste elevii cu nota la Matematica peste media notelor la Matematica.

Ce ai invatat astazi

  • Modelul relational organizeaza datele in tabele cu PK (identifica unic randul) si FK (refera alta tabela)
  • SELECT + WHERE + ORDER BY + GROUP BY + HAVING formeaza blocul de baza al interogarilor SQL
  • INNER JOIN returneaza intersectia tabelelor; LEFT JOIN pastreaza toate randurile din tabela stanga
  • INSERT adauga, UPDATE modifica, DELETE sterge — intotdeauna cu WHERE la UPDATE/DELETE
  • Subinterogarile (IN, =, EXISTS) permit filtrari bazate pe rezultatele altor interogari
  • 1NF: valori atomice; 2NF: dependenta de intreaga PK; 3NF: fara dependente tranzitive

Urmatoarea lectie

Continua cu SQL avansat: subinterogari corelate, JOIN-uri complexe, viste si tranzactii.

Continua →