Pe scurt
O entitate este un tip de obiect despre care păstrăm date, de exemplu „Elev” sau „Clasă”. Atributele descriu entitatea: elevul are identificator și nume. O relație arată asocierea dintre entități: un elev este înscris într-o clasă. Cardinalitatea precizează câte obiecte pot participa: o clasă poate avea mulți elevi.
În detaliu
Proiectarea unei baze de date începe prin identificarea entităților (tipuri de obiecte despre care păstrăm date), a atributelor lor și a relațiilor dintre entități. „Nume” este un atribut al elevului, nu o entitate separată. Cardinalitatea unei relații arată câte înregistrări pot participa la ea și stabilește ce asocieri sunt permise. 1:1: un elev are un carnet școlar unic. 1:N: o clasă are mai mulți elevi, dar fiecare elev aparține unei singure clase în acest model. M:N: mai mulți elevi participă la mai multe cluburi. În modelul relațional, o relație 1:N se reprezintă printr-o cheie externă în tabelul de pe partea „mulți”, o relație 1:1 printr-o cheie externă care este și unică, iar o relație M:N printr-un tabel de legătură cu cheia externă către fiecare entitate.
Exemplul 1 — relațiile 1:N și 1:1. Ana și Dan sunt în clasa 9A, deci există două instanțe „Elev” și o instanță „Clasă”, cu două asocieri către aceeași clasă. Cheia clasei se pune în rândul fiecărui elev. Carnetul este o relație 1:1: cheia lui primară este chiar elev_id, deci un elev nu poate avea două carnete:
CREATE TABLE clase (id integer PRIMARY KEY, denumire text NOT NULL);
CREATE TABLE elevi (id integer PRIMARY KEY, nume text NOT NULL,
clasa_id integer NOT NULL REFERENCES clase(id));
CREATE TABLE carnete (elev_id integer PRIMARY KEY REFERENCES elevi(id),
serie text NOT NULL);
INSERT INTO clase VALUES (9, '9A');
INSERT INTO elevi VALUES (1, 'Ana', 9), (2, 'Dan', 9);
INSERT INTO carnete VALUES (1, 'C-001'), (2, 'C-002');
INSERT INTO carnete VALUES (1, 'C-003');
SELECT COUNT(*) FROM elevi WHERE clasa_id = 9;
Inserarea celui de-al doilea carnet pentru elevul 1 este respinsă, deoarece elev_id este cheie primară. Ultima interogare întoarce 2: clasa 9 are doi elevi. Fiecare elev are o singură clasă, dar clasa are mai mulți elevi, deci cheia externă se află în elevi, nu în clase.
Exemplul 2 — relația M:N. Dacă un elev poate participa la mai multe cluburi și un club are mai mulți elevi, o singură cheie externă în elevi nu este suficientă: ar permite un singur club per elev. Se folosește tabelul de legătură elev_club(elev_id, club_id), în care fiecare rând asociază un elev cu un club:
CREATE TABLE cluburi (id integer PRIMARY KEY, denumire text NOT NULL);
CREATE TABLE elev_club (elev_id integer REFERENCES elevi(id),
club_id integer REFERENCES cluburi(id),
PRIMARY KEY (elev_id, club_id));
INSERT INTO cluburi VALUES (7, 'Robotică'), (8, 'Șah');
INSERT INTO elev_club VALUES (1, 7), (1, 8), (2, 7);
SELECT cluburi.denumire FROM elev_club JOIN cluburi ON club_id = cluburi.id
WHERE elev_id = 1 ORDER BY cluburi.denumire;
SELECT elevi.nume FROM elev_club JOIN elevi ON elev_id = elevi.id
WHERE club_id = 7 ORDER BY elevi.nume;
Prima interogare întoarce Robotică și Șah (cluburile Anei), iar a doua întoarce Ana și Dan (membrii clubului 7). Tabelul de legătură are 3 rânduri, câte unul pentru fiecare asociere. Cardinalitatea nu poate fi ignorată: ea decide unde se pune cheia externă.
Exemplul 3 — atributul unei relații. Un atribut nu aparține întotdeauna unei entități. Anul în care elevul s-a înscris la un club nu descrie nici elevul, nici clubul, ci asocierea dintre ei, deci devine coloană în tabelul de legătură:
ALTER TABLE elev_club ADD COLUMN an integer;
UPDATE elev_club SET an = 2025 WHERE elev_id = 1 AND club_id = 7;
UPDATE elev_club SET an = 2026 WHERE elev_id = 1 AND club_id = 8;
UPDATE elev_club SET an = 2026 WHERE elev_id = 2 AND club_id = 7;
SELECT club_id, an FROM elev_club WHERE elev_id = 1 ORDER BY club_id;
Interogarea întoarce perechile și : aceeași persoană s-a înscris la cele două cluburi în ani diferiți. Dacă anul ar fi pus în tabelul elevi, elevul 1 ar avea o singură valoare pentru ambele cluburi; dacă ar fi pus în cluburi, ar fi aceeași pentru toți membrii. Pentru fiecare atribut se întreabă despre ce este valoarea: dacă depinde de perechea elev–club, locul ei este în tabelul de legătură.
Greșeli frecvente
- Greșit: „nume” este o entitate separată de elev în acest model simplu.Corect: este un atribut al elevului.
- Greșit: o relație mulți-la-mulți se exprimă printr-o singură cheie externă în tabelul elevilor.Corect: cere tabel de legătură.
- Greșit: cardinalitatea poate fi ignorată la proiectare.Corect: ea stabilește ce asocieri sunt permise.
Testează-te pe această lecție
Lecția o citești aici, fără cont. Testele pe lecții și capitole sunt în cont, cu grile originale Didaxis și explicația fiecăreia: gratuit 10 grile pe zi, fără limită cu Premium, 49 de lei pe lună pentru fiecare copil.
Înainte și după
Surse și referințe
Redactare proprie, conform programei:
- OMECI 5099/2009, anexa 5, Informatică, p. 3–4, 7, clasa XII; rocnee.eu
- OMECI 5099/2009, anexa 5, Informatică, p. 3, 7, clasa XII; plan de încadrare: OMEC 7723/2024, anexa 2, tabelele 1–25, legislatie.just.ro; filiera tehnologică: OMEC 7724/2024, anexa 4, tabelul calificării, legislatie.just.ro
Documente consultate
- Programa școlară de informatică, clasa a XII-a (OMECI 5099/2009, anexa 5), CNCE, modulul Baze de date, p. 3 și 7; rocnee.eu
- OpenStax, Introduction to Computer Science, cap. 8.3 „Relational Database Management Systems”, openstax.org/books/introduction-computer-science/pages/8-3-relational-database-management-systems
Desene: Redactare proprie (desen original)
