Documente Academic
Documente Profesional
Documente Cultură
Crearea unui proiect bun de baze de date implică următoarele şase etape:
1°. Modelarea aplicaţiei
2°. Determinarea datelor necesare pentru aplicaţie;
3°. Organizarea datelor în tabele şi stabilirea relaţiilor între acestea;
4°. Stabilirea cerinţelor de indexare şi de validare pentru datele respective;
5°. Crearea şi memorarea interogărilor necesare pentru aplicaţie;
6°. Revederea proiectării.
1
În cele ce urmează vom lua în discuţie etapele de mai sus.
Atunci când modelăm o aplicaţie, primul lucru pe care trebuie să-l facem este să
determinăm sarcinile pe care aplicaţia trebuie să le rezolve. De exemplu atunci când ţinem
evidenţa studenţilor şi a rezultatelor acestora la învăţătură, se ştie că se doreşte posibilitatea
calculului mediei fiecăruia dintre aceştia, a numărului total de credite cumulat de fiecare în
parte şi eventual anumite statistici pe ani, grupe, sex sau alte criterii. Determinând sarcinile ce
trebuiesc rezolvate de către aplicaţie se creează aşa-numita specificaţie funcţională. Atunci
când aplicaţia pe care o creaţi este chiar pentru dumneavoastră, probabil că vă sunt clare toate
sarcinile pe care doriţi ca aplicaţia să le efectueze. Totuşi a scrie aceste sarcini într-un
document de specificaţii este o idee bună. Acest document vă poate ajuta să nu pierdeţi din
vedere nimic din ceea ce doriţi ca programul să rezolve. Dacă însă aplicaţia pe care o creaţi
este pentru altcineva, o specificaţie funcţională poate deveni un acord, o înţelegere cu
utilizatorul, asupra a ceea ce aplicaţia va trebui să rezolve. Aceste specificări pot constitui
jaloane de atins pe parcursul proiectării aplicaţiei.
Atunci când creaţi programul pentru altcineva, cea mai bună cale de a învăţa ce operaţii
trebuiesc efectuate este de a vorbi cu persoana (beneficiarul) în cauză şi a pune întrebări. Ca
un prim pas ar trebui aflat dacă ei nu au deja un sistem pe care doresc să-l înlocuiască cu altul
mai bun, sau dacă au anumite rapoarte pe care doresc să le obţină. Puneţi apoi o sumedenie de
întrebări, până când aţi înţeles scopurile utilizatorului pentru programul pe care vi-l solicită.
Unul din aspectele cheie a unei proiectări eficiente a bazelor de date este determinarea
modului în care datele vor fi organizate în baza de date. Pentru o bună proiectare, datele
trebuiesc organizate într-un mod care să permită o uşoară extragere a informaţiilor şi care să
facă baza de date uşor de întreţinut. În cadrul unei baze de date, datele sunt memorate în una
sau mai multe tabele. Pentru cele mai multe aplicaţii cu baze de date se poate obţine o
organizare eficientă a datelor prin memorarea datelor în mai multe tabele şi prin stabilirea unor
relaţii între aceste tabele.
Tabele. Un tabel este o colecţie de informaţii cu privire la un anumit subiect. Stabilind
un subiect-cheie pentru fiecare tabelă se poate stabili dacă o anumită dată îşi are locul sau nu
în respectivul tabel. De exemplu, dacă instituţia de învăţământ doreşte să ţină o evidenţă atât a
studenţilor cât şi a profesorilor, proiectantul bazei de date ar putea fi tentat să introducă datele
ambelor categorii de persoane în aceeaşi tabelă – ambele necesitând nume, prenume, adresa,
telefon. Totuşi, uitându-ne la datele necesare studenţilor, observăm că pentru aceştia ar fi
necesare şi informaţii cu privire la grupa de care aparţin, la forma de învăţământ (cu sau fără
2
taxă) şi la achitarea sau nu a taxei pentru cei în regim cu taxă. Dacă s-ar crea o singură tabelă
pentru studenţi şi profesori, multe câmpuri ar rămânea astfel necompletate în dreptul
profesorilor. De asemenea ar fi necesar atunci să se adauge un câmp care să facă distincţia
între un student şi un profesor. În mod clar această metodă ar conduce la mult spaţiu de
memorare ocupat fără nici un rost. De asemenea ar rezulta o procesare mai lentă a tranzacţiilor
care vizează numai studenţii sau numai profesorii, deoarece programul va trebui să sară tot
timpul peste anumite înregistrări din tabel care nu interesează. Figura 1.1. arată o tabelă de
bază de date cu cele două categorii (studenţi şi profesori) combinate. Figura 1.2. arată
reducerea numărului de câmpuri într-un tabel doar cu profesorii.
Figura 1.1. Combinarea într-o singură tabelă a studenţilor şi profesorilor duce la risipă mare de spaţiu
Figura 1.2. O tabelă separată pentru profesori conţine doar câmpurile care interesează şi este mai
eficientă
3
numit în acest exemplu ProfId – aceasta de asemenea pentru a nu încărca tabela notelor cu
toate informaţiile suplimentare care există în tabelul Profesori cu privire la un anumit profesor.
Observaţie. Aceste câmpuri de identificare, StudId din tabelul Studenti şi ProfId din
tabelul Profesori conţin întotdeauna valori unice, distincte. Ele vor constitui şi chei primare
în respectivele tabele. Aceasta înseamnă, spre exemplu, că o anumită valoare a lui StudId
poate exista doar pentru o singură înregistrare din tabelul Studenti şi nu poate fi duplicată.
Astfel va putea fi distins un anumit student de altul, chiar dacă cei doi ar avea nume identice,
şi poate – prin absurd – şi adrese sau orice alte câmpuri identice.
Prin urmare, dacă se plasează toate aceste date cu privire la notele studenţilor într-o
singură tabelă, rezultatul ar arăta asemănător ce ceea se poate vedea în figura 1.3. Deja aici
citirea tabelei se complică la o simplă privire fugară, deoarece în locul numelor studentului şi
al profesorului avem numerele de identificare a acestora, care trebuie să ne facă legătura cu
tabelele Studenti şi Profesori pentru a putea afla cine sunt aceştia.
4
Fig. 1.4. Normalizarea completă a tabelelor asigură eficienţă maximă.
5
Figura 1.5. Reprezentarea relaţiilor între tabelele unei baze de date în Microsoft Access
Practic nu există reguli absolute care să delimiteze care date în care tabele trebuiesc
introduse, dar, cu toate acestea am putea enumera câteva reguli generale care ar trebui urmărite
pentru a proiecta o bază de date bine structurată. Acestea ar fi:
Orice tabel trebuie să aibă o temă, de exemplu „Informaţii despre abonaţi” sau
„Tranzacţii ale clienţilor”. Încercaţi să vă limitaţi la o singură temă pe tabel.
Spargeţi tabela în două tabele similare în cazul în care un număr de înregistrări au
câmpuri lăsate necompletate în mod intenţionat (ca şi despărţirea tabelei Profesori de
tabela Studenti).
Mutaţi într-o altă tabelă a informaţiilor care se repetă într-un număr de înregistrări şi
stabiliţi o relaţie între acele tabele.
Dacă există o listă cu informaţii de referinţă, pe care vreţi să o păstraţi (cum ar fi
disciplinele şi numărul de credite aferente fiecăreia), puneţi-le în propriul tabel.
Unde este posibil, folosiţi numere de identificare, ele ajutându-vă să legaţi tabele între
ele şi să evitaţi greşelile de dactilografie datorate introducerii unor şiruri lungi de date
(cum sunt numele).
Nu stocaţi informaţii într-un tabel dacă acestea pot fi calculate din datele altor tabele.
Adeseori, din motive de performanţă, se ocolesc unele din aceste reguli. De exemplu,
dacă pentru a obţine vânzările totale pentru un anumit vânzător este necesară însumarea mai
6
multor mii de înregistrări, poate se merită a include un câmp de Vanzari totale în tabela
Vanzatori, câmp care să fie actualizat de câte ori se face o vânzare. În acest fel, atunci când
sunt generate rapoarte, aplicaţia nu va trebui să efectueze un număr mare de calcule şi procesul
de raportare va fi mult mai rapid.
Un alt motiv pentru a devia de la aceste reguli este evitarea deschiderii unui număr prea
mare de tabele în acelaşi timp. Aceasta deoarece fiecare tabelă deschisă utilizează resurse
preţioase şi de asemenea spaţiu de memorare, încât aplicaţia ar putea pierde considerabil din
viteză.
Pe de altă parte, devierea de la aceste reguli de structurare a tabelelor conduce la două
probleme majore:
– creşterea mărimii bazei de date din cauza datelor redundante;
– posibilitatea de a avea la un moment dat date incorecte din cauză că s-a modificat
conţinutul anumitor câmpuri şi, dintr-un motiv sau altul, nu toate înregistrările afectate au fost
actualizate.
În concluzie va trebui căutat un optim între performanţa aplicaţiei şi eficienţa stocării
datelor în tabele.
Atunci când se introduc date într-un tabel, înregistrările sunt stocate în general în
ordinea în care ele sunt introduse. Aceasta este ordinea fizică a datelor. De obicei însă
utilizatorii doresc să proceseze datele într-o ordine diferită de cea în care au fost introduse
înregistrările în tabele. Aceasta presupune definirea unei aşa-numite ordini logice. Această
ordine logică va fi de asemenea utilă atunci când se va dori căutarea într-un tabel a unei
anumite înregistrări.
Indexarea este metoda cel mai des utilizată de a ordona tabelele de date. Un index este
de asemenea o tabelă, care conţine o valoare cheie (derivată de obicei din valorile a unul sau
mai multe câmpuri) pentru fiecare înregistrare din tabela de date; indexul însuşi este memorat
într-o ordine logică specifică şi conţine pointeri (indicatori de adrese) care spun motorului de
baze de date unde este localizată înregistrarea curentă.
Indecşii sunt setaţi la proiectarea tabelei cu scopul de a mări viteza şi de a garanta
unicitatea unei înregistrări. Cartea de telefoane de exemplu este o listă indexată după nume.
Atunci când căutaţi numărul de telefon al unei persoane îl puteţi găsi rapid uitându-vă doar la
câteva pagini, dacă ştiţi care este numele persoanei. Dacă numerele de telefon ar fi date în
cartea de telefon în ordinea în care au fost ele atribuite abonaţilor, o astfel de carte nu ar folosi
nimănui, fiind aproape imposibil de a găsi numărul unei anumite persoane.
O tabelă poate avea mai mulţi indecşi diferiţi asociaţi, pentru a asigura pentru anumite
situaţii ordonarea datelor într-un fel sau în altul. De exemplu tabela studenţilor ar putea fi utilă
în ordine alfabetică a acestora sau poate în ordinea grupelor şi eventual alfabetic în cadrul
fiecărei grupe sau, poate, descrescător după media rezultată în urma introducerii notelor de
examen. Fiecare index arată aceleaşi date într-o ordine diferită, pentru un scop diferit.
Observaţii.
1. Chiar dacă este de dorit să putem avea vederi diferite asupra datelor în toate
ordonările posibile, trebuie avut în vedere că pentru baze de date mari a menţine o varietate
foarte mare de indecşi poate prejudicia performanţa aplicaţiei, deoarece toţi indicii trebuie
actualizaţi ori de câte ori datele se modifică. Şi în această problemă programatorul aplicaţiei
va trebui să aleagă o variantă optimă de compromis.
2. Se pot însă crea diferite vederi a informaţiilor dintr-un tabel şi prin sortarea
înregistrărilor sau prin specificarea unei ordini dorite utilizând clauza ORDER BY a unei
comenzi SQL (Structured Query Language). Chiar dacă indecşii nu sunt utilizaţi direct de un
motor SQL, prezenţa lor măresc viteze procesului de sortare atunci când există o clauză
ORDER BY.
7
Indexul poate fi un câmp sau o combinaţie de câmpuri, iar câmpurile ar putea necesita
valori unice sau nu. Dacă un index necesită o valoare unică, el este denumit index unic.
Cele mai obişnuite tipuri de indecşi sunt cei cu expresii cheie singulare, adică cei
bazaţi pe valoarea unui singur câmp din tabel. Exemple de astfel de indecşi sunt identificatorul
de student (StudId) sau numele studentului (Nume) sau grupa (Grupa) etc. pentru tabela
Studenti. Atunci când există mai multe înregistrări cu aceeaşi valoare a cheii de indexare, aşa
cum ar putea fi cazul cu numele studentului sau cum este sigur cazul cu indexarea după grupă,
înregistrările multiple sunt prezentate în ordinea fizică în cadrul ordinii impuse de indexul
cheie singular. Figura 1.6 arată cum va arăta tabela Studenti (cu ordinea fizică dată în figura
1.2) în urma indexării după câmpul Grupa.
Totuşi, nu de puţine ori ar putea fi necesară o ordine mai exactă. Acest lucru se poate
face utilizând expresii cu chei de indexare multiple. După cum şi numele o spune, indexul
cheie multiplă se bazează pe valorile din două sau mai multe câmpuri ale unui tabel. Un
exemplu ar fi să indexăm tabelul Studenti după grupă şi în cadrul grupei alfabetic după nume
(şi poate chiar la nume identice alfabetic după prenume). Dacă totuşi există înregistrări care să
aibă aceiaşi valoare cheie pentru două sau mai multe înregistrări, acestea vor apărea ca şi în
cazul indecşilor cu chei singulare în ordinea fizică a înregistrărilor. În figura 1.7 se poate
vedea tabela Studenti indexată cu o cheie multiplă după Grupa, Nume şi Prenume.
Figura 1.7. Tabela Studenti cu index cheie multiplă după câmpul Grupa, Nume şi Prenume
Atunci când normalizaţi datele, de obicei plasaţi informaţiile înrudite în mai multe
tabele relaţionale. La accesarea datelor însă, veţi dori să vedeţi informaţiile din toate tabelele
într-un singur loc, denumit tabelă virtuală (view). Această tabelă practic nu există ca atare, dar
în baza de date este memorată descrierea ei. Această descriere precizează că datele view-ului
provin dintr-o porţiune a unei tabele, din mai multe tabele ori din mai multe porţiuni ale mai
multor tabele. Pentru a reuşi acest lucru este necesară crearea de seturi de înregistrări, care să
consolideze informaţiile legate prin relaţii şi aflate în două sau mai multe tabele.
Un set de înregistrări se creează din mai multe tabele utilizând o comandă SQL care
specifică numele câmpurilor dorite, locaţia câmpurilor şi relaţia dintre tabele. Comanda SQL
8
se poate însă memora ca o interogare (Query) în baza de date. (A se vedea capitolul cu privire
la comenzile SQL).
Microsoft Access are o interfaţă vizuală de proiectare foarte facilă, pentru a defini
tabele, indecşi, interogări şi relaţii între tabele. Este evident instrumentul cel mai performant
de lucru cu bazele de date, mult superior lui Visual Data Manager, care are încă unele lipsuri
mari (de exemplu pentru operaţia simplă de modificare a tipului unui câmp dintr-o structură
existentă a unui tabel trebuie recurs la artificii destul de complicate).
Foarte pe scurt va fi prezentată în continuare crearea bazei de date Catalog.mdb şi a
uneia din tabelele acesteia, de exemplu tabela Studenti.
Crearea unui fişier nou de tip bază de date se face selectând File | New | Blank
Database şi alegând apoi folderul şi tastând numele ( Catalog) pentru noul fişier .mdb care
va fi creat. La clic pe butonul Create va apare fereastra, în cazul de faţă Catalog : Database,
fereastră ce va conţine toate obiectele bazei de date care – după dorinţă – se vor adăuga pe
parcurs, ca: tabele (Tables), interogări (Queries), formulare (Forms), rapoarte (Reports) etc.
(vezi figura 1.8).
Acum utilizatorul are posibilitatea să creeze noile tabele ale bazei de date alegând una
din cele trei variante afişate în fereastra din figura 1.8:
Create table in Design view – varianta pe care o vom utiliza efectiv mai jos;
Create table by using the wizard – varianta care ne conduce la alegerea unei
structuri de tabel cu ajutorul unui vrăjitor, utilizând modele de structuri tabelare
pentru cele mai diverse aplicaţii economice, de afaceri, etc.;
Create table by entering data – o variantă simplistă şi cu facilităţi reduse de a
defini un tabel prin introducerea liniilor de date în acesta şi denumirea coloanelor
cap de tabel, care vor deveni numele câmpurilor respective.
Se recomandă în general prima din variantele de mai sus ca fiind cea mai flexibilă şi
performantă modalitate de a defini o tabelă.
Alegând cu un dublu clic de mouse prima din cele trei variante, va apare o fereastră
Table pentru definirea structurii noii tabele, ca cea din figura 1.9, în care se introduc pe rând
numele câmpurilor, se alege din lista derulantă (Data Type) tipul dorit (Text, Memo, Number,
Date/Time etc.) şi se dă o eventuală descriere a câmpului (un comentariu) în rubrica
Description. În partea de jos a ferestrei Table, pagina General vor putea fi setate proprietăţi
suplimentare cu privire la câmpul respectiv, proprietăţi care depind de tipul câmpului ales.
9
Figura 1.9. Fereastra Table pentru definirea structurii unei tabele
Observaţii.
1. Pentru datele de tip Text proprietatea FieldSize indică lungimea în număr de
caractere a câmpului.
2. Pentru datele numerice Number, proprietatea FieldSize oferă o listă de subtipuri
numerice, ca Long Integer (valoarea implicită), Byte, Integer, Single, Double etc.
din care se poate alege cea care corespunde cel mai bine tipului de date care va fi
stocat în respectivul câmp.
3. Valoarea implicită cu care se iniţializează un câmp la adăugarea unei noi
înregistrări este specificată de proprietatea DefaultValue.
4. Dacă proprietatea Required are valoarea Yes, atunci trebuie să se dea o valoare
pentru câmpul respectiv. Câmpul nu poate rămâne necompletat în varianta că mai
târziu o valoare va fi oricum precizată.
5. Câmpurile de tip Text şi Memo pot avea ca valoare şiruri de lungime 0 (vid) dacă
proprietatea AllowZeroLength are valoarea Yes.
6. Proprietatea ValidationRule permite precizarea unei condiţii de validare a
câmpului respectiv, (de exemplu: >0 în dreptul unui câmp numeric).
7. Dacă eventuala regulă precizată de proprietatea ValidationRule nu este
îndeplinită, atunci se poate afişa un mesaj de eroare precizat prin proprietatea
ValidationText.
8. Cu proprietatea Format se poate specifica un format de afişare a valorii câmpului,
format care poate fi în general ales dintr-o listă derulantă care este diferită de la
un tip de date la altul.
9. Pentru tipurile de date Text sau Date/Time proprietatea InputMask oferă
posibilitatea de a preciza un şablon de introducere a datelor, ca de exemplu un
anumit şablon pentru introducerea numerelor de telefon (care, având de multe ori
zerouri în faţă, trebuiesc declarate de tip Text şi nu Number!) sau pentru
introducerea datelor calendaristice.
10. Proprietatea Caption precizează un şir de caractere care se ataşează câmpului şi
care va apărea ca şi cap de coloană în locul numelui acestuia, atunci când se va
deschide tabela (cu meniul Open din fereastra Database).
11. Proprietatea Indexed se referă la crearea unui index sau nu pe baza valorilor
câmpului respectiv, şi permite alegerea uneia din următoarele trei variante:
- No – nu se indexează după respectivul câmp;
- Yes (Duplicates OK) – se indexează după câmpul respectiv, care poate avea
valori identice în două sau mai multe înregistrări;
- Yes (No Duplicates) – se indexează după câmpul respectiv, nefiind permise
valori identice în două sau mai multe înregistrări.
După definirea structurii tabelei prin completarea câmpurilor în fereastra Table şi a
proprietăţilor acestora, se închide fereastra Table cu butonul de închidere. Va apare o fereastră
cu întrebarea: Do you want to save changes to the design of Table1?, la care desigur că se va
10
răspunde cu Yes pentru a salva structura definită anterior, urmând a da apoi numele tabelei,
respectiv Studenti. Dacă pentru tabela respectivă nu s-a definit nici o cheie primară, va apare
mesajul din figura 1.10:
La întrebarea din mesaj se poate alege Yes, caz în care se va crea un câmp nou cu
numele ID de tip Autonumber (număr cu autoincrementare de la o înregistrare la alta), care va
fi considerat cheie primară, sau No, caz în care se salvează structura tabelei aşa cum era, fără
nici o cheie primară. Dacă se alege răspunsul Cancel se revine în fereastra de definire a
structurii Table fără a se efectua nici o salvare.
În cazul că s-a ales unul din răspunsurile Yes sau No, structura tabelei a fost creată şi în
fereastra Database a apărut tabela Studenti (vezi figura 1.11).
Dacă după ce s-a salvat tabela sub numele Studenti se constată că s-a greşit sau s-a
uitat ceva la definirea structurii tabelei, se selectează tabela Studenti din fereastra 1.11 şi se
alege din meniul contextual al acesteia Design View (sau se dă clic pe butonul ).
Astfel se deschide din nou fereastra Table, în care se pot insera sau şterge linii (cu
comenzile Insert Rows sau Delete Rows din meniul contextual atunci se selectează o anumită
linie), se pot redenumi câmpuri sau modifica proprietăţile acestora, se pot adăuga proprietăţi
de indexare, reguli de validare etc. ca şi la crearea structurii unei tabele noi, respectiv se poate
alege ca un anumit câmp să devină cheie primară de indexare (selectând linia cu câmpul
respectiv şi dând un clic pe butonul Primary Key din bara de unelte standard Microsoft
Access atunci când este deschisă o tabelă în modul Design view). În final, structura tabelei
Studenti în fereastra Design view ar arăta ca în figura 1.12.
11
Figura 1.12. Structura tabelei Studenti în modul Design view
Observaţi în figura 1.13 că NumPre este numele unui index câmp multiplu, în care
indexarea se va face în primul rând crescător după nume, iar la nume identice după prenume.
După efectuarea tuturor modificărilor se închide fereastra Table şi apare o fereastră cu
mesajul: Do you want to save changes to the design of table ′Studenti′ ?, la care, pentru a salva
toate modificările, se răspunde cu Yes.
Pentru a introduce date în tabelele create se dă dublu clic pe tabela dorită din fereastra
Databases (sau se alege opţiunea Open din meniul contextual care apare la un clic dreapta de
mouse pe tabele selectată, sau se alege butonul ) – a se vedea figura 1.11. În fereastra
apărută se introduc datele dorite, ca în figura 1.14.
12
Observaţie. În general, datele vor fi introduse prin program şi nu în modul prezentat
mai sus. S-a dat şi varianta aceasta doar ca exemplu didactic.
În ceea ce priveşte crearea relaţiilor, Microsoft Access oferă o reprezentare vizuală
foarte sugestivă a relaţiilor dintre tabelele unei baze de date. Această reprezentare permite
utilizatorului să tragă o linie între câmpurile relaţionale din tabele sau interogări. Astfel, din
mediul Access dacă alegem opţiunea Relationships... din meniul Tools sau dăm clic pe
icon-ul corespunzător din bara de unelte standard, obţinem o fereastră intitulată
Relationships. Cu un simplu clic dreapta oriunde în această fereastră putem adăuga, prin
intermediul opţiunii Show Tables, câte o tabelă a bazei de date. Apoi, cu metoda
drag-and-drop se „trasează” practic relaţiile dintre tabele, unind câmpurile care fac legătura
între două tabele. Butonul de mouse se eliberează când indicatorul mouse-ului va deveni un
mic dreptunghi fixat pe câmpul destinaţie. În caseta de dialog Relationships care apare se
cere definirea legăturii pe care vrem să o realizăm. Tot aici, de obicei, se bifează opţiunea
Enforce Referential Integrity, care are rolul de a ne împiedica să facem greşeli la
introducerea datelor.
În cazul exemplului discutat mai sus, relaţiile sunt reprezentate în Microsoft Access ca
în figura 1.5 de la paragraful 1.1.3.1.
Câmpurile îngroşate reprezintă chei primare în tabelele respective, iar simbolurile
legăturilor (cifra 1 şi simbolul ) indică faptul că, spre exemplu, unei singure înregistrări
din tabelul Studenti, îi pot corespunde mai multe înregistrări din tabelul Note.
13