webroad.online
  1. 1Web
  2. 2HTML
  3. 3CSS
  4. 4JavaScript
  5. 5TypeScript
  6. 6Git
  7. 7Unelte
  8. 8React
  9. 9State management
  10. 10Next.js
  11. 11Formulare
  12. 12Date și backend
  13. 13SEO
  14. 14Tailwind CSS
  15. 15Animații
  16. 16Testare
  17. 17Arhitectură
Date și backend · Lecția 2 din 4

SQL și baze de date relaționale

Tabele, chei, CRUD, JOIN, relații și query-uri parametrizate.

Actualizat

Ce este o bază de date relațională

O bază de date relațională (PostgreSQL, MySQL, SQLite) ține datele în tabele: fiecare tabel are coloane cu tipuri fixe, iar fiecare rând e un element. Tabelele se leagă între ele prin chei — de aici „relațional”.

users                         posts
id | name  | email            id | user_id | title
---+-------+------------      ---+---------+---------
 1 | Ana   | ana@x.ro          1 |       1 | Salut
 2 | Ion   | ion@x.ro          2 |       1 | Next 16

SQL e limbajul cu care întrebi și modifici aceste date. Chiar dacă folosești un ORM, SQL-ul e ce rulează de fapt — merită să-l citești fluent. Aplicația asta folosește PostgreSQL pe Neon.

Cheile

Cheie Rol
primary key identifică unic un rând (id)
foreign key coloană care indică spre cheia altui tabel (posts.user_id → users.id)
unique valoare care nu se poate repeta (email)
index structură care face căutările pe o coloană rapide

Cele 4 operații (CRUD)

SELECT id, title FROM posts WHERE user_id = 1 ORDER BY created_at DESC LIMIT 10;

INSERT INTO posts (user_id, title) VALUES (1, 'Salut') RETURNING id;

UPDATE posts SET title = 'Salut!' WHERE id = 1;

DELETE FROM posts WHERE id = 1;

UPDATE și DELETE fără WHERE afectează toate rândurile. Primul lucru pe care îl verifici.

SELECT pe bucăți

Clauză Rol Echivalent JS
SELECT col1, col2 ce coloane map
FROM tabel din ce tabel array-ul
WHERE cond ce rânduri filter
ORDER BY col DESC ordinea toSorted
LIMIT n OFFSET m câte, de unde slice
GROUP BY col + COUNT(*) grupare și agregare Object.groupBy + length

JOIN — combini tabele

SELECT posts.title, users.name
FROM posts
JOIN users ON users.id = posts.user_id;
Tip Păstrează
JOIN (inner) doar rândurile care au pereche în ambele tabele
LEFT JOIN toate rândurile din stânga; dreapta = NULL dacă lipsește perechea

Relații — tipuri

Relație Exemplu Cum se modelează
one-to-many un user → multe postări posts.user_id
many-to-many postări ↔ taguri tabel de legătură post_tags (post_id, tag_id)
one-to-one user → profil profiles.user_id unique

SQL injection — regula de aur

Niciodată nu lipești input de la user direct în textul SQL:

sql(`SELECT * FROM users WHERE email = '${email}'`)       // ✗ email = "' OR '1'='1" → toți userii
sql`SELECT * FROM users WHERE email = ${email}`            // ✓ parametru — trimis separat de query

Template-ul sql`...` din @neondatabase/serverless (folosit în aplicația asta), ORM-urile și query builder-ele trimit valorile ca parametri ($1, $2), niciodată ca text.

Pe scurt

  • Tabele cu coloane tipate, legate prin primary / foreign keys.
  • SELECT … WHERE … ORDER BY … LIMIT, INSERT, UPDATE … WHERE, DELETE … WHERE; JOIN pentru relații.
  • Mereu query-uri parametrizate — niciodată input lipit în text.

Surse oficiale

Exerciții

Ți-a fost utilă pagina?

Un click — fără cont.