Sunteți pe pagina 1din 25

7

BAZE DE DATE 1
ÎN VISUAL FOXPRO

1.1. Elemente de teoria b azelor de date 1

Evoluţia metodelor şi tehnicilor de organizare a datelor a fost determinată de necesitatea de a avea un


acces cât mai rapid şi mai uşor la un volum din ce în ce mai mare de informaţii.
În esenţă conceptul de bază de date 1 poate fi definit ca fiind una sau mai multe colecţii de date aflate
în interdependenţă, împreună cu descrierea datelor precum şi a relaţiilor dintre acestea. Baza de date astfel
definită trebuie să îndeplinească următoarele condiţii:
• să asigure o independenţă sporită a datelor faţă de programe şi invers;
• structura bazei de date trebuie să asigure informaţiile necesare şi suficiente pentru cerinţele de
informare şi decizie;
• să asigure o redundanţă minimă şi controlată a datelor;
• să permită accesul rapid la informaţiile memorate.
Bazele de date sunt extrem de variate, existând diferite criterii de clasificare, şi anume:
• după orientare: generalizate, specializate;
• după modelul de date: ierarhice, reţea, relaţionale, orientate obiect;
• după amploarea geografică: locale, distribuite;
• după limbajele utilizate: autonome (limbaje proprii), cu limbaj gazdă, mixte.
Arhitectura bazelor de date evidenţiază componentele acestora, cuprinzând în general următoarele :
• baza de date propriu-zisă în care se memorează datele;
• un dicţionar al bazei de date (metabaza de date), ce conţine informaţii despre date, structura
acestora, elementele de descriere a semanticii, statistici, documentaţie, etc.;
• sistemul de gestiune al bazei de date, reprezentând ansamblul de programe cu ajutorul căruia se
realizează gestiunea şi prelucrarea complexă a datelor;
• un set de proceduri manuale şi automate destinate bunei funcţionări a întregului sistem;
• mijloacele hard utilizate;
• personalul implicat: deosebim următoarele categorii de utilizatori: finali (neinformaticieni), de
specialitate (administratori), analişti-programatori, gestionari, operatori.
Într-o bază de date, organizarea datelor poate fi analizată din mai multe puncte de vedere. De obicei,
abordarea efectuându-se pe trei nivele: fizic sau intern, conceptual sau global şi extern.
Nivelul fizic este un nivel de abstractizare al datelor elementar la care pot fi considerate datele,
reprezentând modalitatea efectivă în care acestea sunt memorate pe suportul infomaţional. Structura datelor
este descrisă detaliat, fiind accesibilă numai specialiştilor (ingineri de sistem, programatori în limbaj de
asamblare sau alte limbaje apropiate de “maşină”). La acest nivel, structura bazei de date se concretizează în
aşa-numita schemă internă.

1
Lungu I., Bodea C., Bădescu G., Ioniţă C., Baze de date. Organizare, proiectare şi implementare, Editura ALL, 1995
8

Nivelul conceptual (sau global) este nivelul imediat superior celui fizic, datele fiind privite prin
prisma semanticii lor, punându-se accent pe conţinutul lor efectiv şi pe relaţiile care le leagă de alte date.
Întreaga bază de date este descrisă prin intermediul unui număr restrâns de structuri care, deşi relativ simple,
prin transpunerea la nivel fizic devin extrem de complexe. Toţi utilizatorii îşi exprimă cerinţele de date la
nivel conceptual, prezentându-le administratorului bazei de date, acesta fiind cel care are o viziune globală
asupra organizării bazei concretizată printr-o schemă conceptuală aferentă.
Nivelul extern este ultimul nivel de abstractizare la care poate fi descrisă o bază de date. El este dat de
viziunea programatorului de aplicaţii, care realizează programele de aplicaţii pentru manipularea datelor şi
structura logică (subschema) corespunzătoare descrierii datelor aplicaţiei. Dacă la nivel conceptual baza de
date era abordată în ansamblul ei, în practică, un utilizator sau un grup de utilizatori lucrează numai cu o
porţiune specifică a bazei de date, în funcţie de departamentul în care îşi desfăşoară activitatea şi atribuţiile
sale (lor). Pentru a simplifica interacţiunea utilizator-bază de date se recurge la nivelul extern, în care baza de
date se prezintă sub diferite machete, sub-scheme sau scheme externe specifice necesităţilor fiecăriu
utilizator sau grup de utilizatori.
Sistemul de gestiune al bazei de date reprezintă software-ul propriu-zis al acesteia asigurând
realizarea următoarelor activităţi:
• definirea structurii bazei de date;
• încărcarea datelor în baza de date;
• accesul la date (consultare, interogare);
• întreţinerea bazei de date (colectarea şi refolosirea spaţiilor goale, refacerea bazei de date în
cazul unui incident);
• reorganizarea bazei de date (restructurarea şi modificarea strategiei de acces);
• securitatea datelor.
Aşadar, sistemul de gestiune al bazei de date apare ca un sistem complex de programe care asigură
interfaţa între o bază de date şi utilizatorii acestuia. În acest context, sistemului de gestiune al bazei de date îi
revin o serie de obiective:
• asigurarea independenţei datelor: independenţa datelor trebuie privită din două puncte de
vedere: independenţa fizică a datelor ce face ca memorarea datelor precum şi tehnicile fizice de
memorare să poată fi modificate fără a determina rescrierea programelor de aplicaţie, iar
independenţa logică a datelor ce se referă la posibilitatea adăugării de noi articole de date sau
extinderea structuri conceptuale (globale), fără ca aceasta să impună rescrierea programelor
existente;
• asigurarea unei redundanţe minime şi controlate a datelor din baza de date: memorarea
datelor, în cazul bazelor de date, se face astfel încât fiecare dată să apară o singură dată; totuşi,
nu sunt excluse nici cazurile în care, pentru a realiza performanţe sporite, referitoare la timpul de
acces la date şi răspuns la solicitările uilizatorilor, să se accepte o anumită redundanţă a datelor,
în acest caz însă instituidu-se un control automat în vederea asigurării coerenţei datelor din bază;
• asigurarea unor facilităţi sporite de utilizare a datelor: aceasta presupune:
– folosirea datelor de către mai mulţi utilizatori în diferite scopuri;
– accesul cât mai simplu al utilizatorului la date;
– existenţa unor limbaje performante de regăsire a datelor;
– posibilitatea unui acces multicriterial, fără sortări suplimentare;
– utilizarea unui limbaj cât mai apropiat de limbajul natural, cu posibilitatea exploatării
în mod facil a bazei de date şi de către utilizatorii neinformaticieni;
• sporirea gradului de securitate a datelor împotriva accesului neautorizat la ele;
• asigurarea integrităţii datelor împotriva unor ştergeri intenţionate sau neintenţionate, prin
intermediul unor proceduri de validare, a unor protocoale de control concurent şi a unor
proceduri de refacere a bazei de date după incidente;
9

• asigurarea partajabilităţii datelor: partajabilitatea datelor trebuie înţeleasă nu numai sub


aspectul asigurării accesului mai multor utilizatori la aceleaşi date, ci şi acela al posibilitătii
dezvoltării unor aplicaţii fără a se modifica structura bazei de date.
Pentru realizarea obiectivelor enumerate mai sus, sistemele de gestiune a bazelor de date dispun de
o serie de componente ce permit efectuarea numeroaselor operaţii. Se pot astfel deduce câteva funcţii cu
caracter de generalitate pentru toate sistemele de gestiune a bazelor de date, şi anume:
• funcţia de descriere a datelor: permite definirea structurii bazei de date cu ajutorul limbajului
de definire; definirea datelor poate fi realizată la nivel logic, conceptual şi fizic; la nivelul acestei
funcţii se descriu multitudinea atributelor (câmpurilor) din cadrul structurii bazei de date,
legăturile dintre entităţile de date sau dintre atributele aceleaşi entităţi, se definesc eventualele
criterii de validare a datelor, metodele de acces la date, aspectele referitoare la asigurarea
integrităţii şi confidenţialităţii datelor, etc; rezultatul acestei funcţii va fi schema bazei de date,
memorate în cod intern;
• funcţia de manipulare a datelor este cea mai complexă funcţie şi realizează următoarele
activităţi:
– crearea (încărcarea) bazei de date;
– adăugarea de noi înregistrări (tupluri);
– suprimarea unor înregistrări;
– modificarea valorilor corespunzătoare unor câmpuri;
– căutarea, sortarea şi editarea parţială şi totală a unei înregistrări virtuale etc.; funcţia de
manipulare a datelor se realizează prin intermediul limbajului de manipulare a datelor;
• funcţia de utilizare asigură mulţimea interfeţelor necesare pentru comunicarea tuturor
utilizatorilor cu baza de date; în cadrul realizării acestei funcţii, apar mai multe categorii de
utilizatori:
– utilizatori conversaţionali: aceştia reprezintă categoria beneficiarilor de informaţii care
utilizează limbajele de interogare a bazei de date într-o formă simplistă;
– utilizatori programatori, care utilizează limbajele de manipulare, realizând proceduri
complexe de exploatare a bazei de date;
– administratorul bazei de date apare ca un utilizator special şi are rolul hotărâtor în ceea
ce priveşte funcţionarea optimă a întregului ansamblu;
• funcţia de administrare a bazei de date apare ca o funcţie complexă şi este de competenţa
administratorului acesteia.

1.1.1 Diagrama Entitate - Asociere


Nivelul conceptual este nivelul central care reflectă datele structurate astfel încât acestea să poată fi
preluate şi prelucrate cu ajutorul unui SGBD. În proiectarea bazelor de date, la nivel conceptual, se pot
utiliza mai multe modele, dintre care cel mai frecvent utilizat în ultima vreme este modelul entitate - asociere
(EA). Modelul EA 2 abstractizează lumea reală şi o transpune, pe de o parte, în angregări de date, numite
entităţi, iar pe de altă parte, în legături între entităţi, denumite corespondenţe, asocieri sau relaţii.
O entitate este un model de obiect identificat în lumea reală - material, imaterial (eveniment) sau
abstract - al cărui tip este definit de un nume şi de o listă de proprietăţi (atribuite). Un atribut se defineşte ca
fiind o proprietate a unei entităţi sau a unei corespondenţe, mulţimea realizărilor (valorilor) sale formând un
domeniu. Mulţimea formată din câte o valoare a fiecărui atribut al unei entităţi reprezintă o realizare
(instanţiere) a entităţii respective. Spunem că există o dependenţă funcţională între două atribute atunci
când unei valori a unei proprietăţi îi corespunde o singură valoare a altei proprietăţi. Identificatorul unei2
entităţi este atributul (sau grupul de atribute) a cărui realizare caracterizează în mod unic o realizare a

2
Năstase P., Cosăcescu L., Mihai F., ş.a., Baze de date. Microsoft Access 2002, Editura Teora, 1999
10

entităţii. Putem avea o dependenţă funcţională între identificatorii a două entităţi. O corespondenţă sau
asociere sau relaţie reprezintă o legătură logică între două sau mai multe realizări de entităţii. Rolul unei
entităţi este un nume care desemnează modul de participare al entităţii la o asociere. Identificarea asocierilor
se realizează prin rolurile entităţilor participante deci, concret, cu ajutorul identificatorilor entităţilor
respective. Mulţimea entităţilor care participă la o asociere formează colecţia acesteia, numărul acestora
reprezentând gradul sau dimensiunea asocierii. O corespondenţă între realizări diferite ale aceleeaşi
entităţi se numeşte asociere reflexivă, caz care se recomandă precizarea rolurilor fiecărei entităţi în cadrul
asocierii. O entitate poate participa la mai multe corespondenţe; în acelaşi timp, pot exista mai multe asocieri
între aceleaşi entităţi. Un subansamblu de entităţi ale aceluiaşi tip de entitate formează un subtip al entităţii
respective cu proprietăţi specifice.
În cadrul modelului EA de abstractizare a unui ansamblu de date trebuie să se ţină cont de
următoarele reguli:
• o asociere (relaţie) nu poate exista decât o singură dată între aceleaşi entităţi;
• numele entităţilor, corespondenţele (relaţiilor), rolurilor, atributelor trebuie să fie unice în cadrul
modelului conceptual, iar apoi în baza de date definită.

1.1.2 Modelul relaţional


Acesta a fost conceput şi dezvoltat de Codd, constituind un model formal de organizare conceptuală a
datelor, destinat reprezentării legăturilor dintre date, bazat pe teoria matematică a relaţiilor. Este modelul cel
mai accesibil pentru utilizatorul bazei de date, deoarece are aceeaşi structură fizică cu datele care trebuie
prelucrate. În general, datele se prezintă sub forma unor tabele (relaţii 3 ) în care liniile constituie entităţi, iar
coloanele atribute ce caracterizează aceste entităţi.
Spre deosebire de modelul ierarhic şi reţea unde apar două elemente, şi anume tipul entităţii şi relaţiile
dintre două entităţi, modelul relaţional este alcătuit numai din relaţii şi prin urmare, orice integrare asupra
bazei de date este tot o relaţie. Modelul relaţional a fost definit cu o deosebită rigoare matematică, furnizând
un mijloc performant de studiu al proprietăţilor logice ale unui sistem de baze de date.
Definirea unui SGBD relaţional impune analizarea caracteristicilor pe care trebuie să le prezinte un
model de date pentru a fi considerat relaţional. Dintre diferitele modalităţi de definire ale acestui concept,
exemplificăm cu:
• prezentarea datelor în tabele supuse anumitor operaţii: proiecţie, selecţie, reuniune, compunere,
intersecţie etc (definiţie simplă);
• un sistem de baze de date ce suportă un limbaj SQL - Structure Query Language (definiţie
practică);
• un sistem de baze de date care respectă principiile modelului relaţional introdus de Codd
(definiţia cea mai frecvent folosită).
Codd a publicat un set de 13 reguli, în raport cu care un SGBD poate fi apreciat ca fiind relaţional.
Ulterior, cele 13 reguli de fidelitate ale lui Codd au fost extinse la un număr de 100. Trebuie remarcat că nu
există un SGBD care respectă toate regulile definite de Codd. De fapt, nu trebuie să apreciem un SGBD ca
fiind relaţional sau nu, ci măsura în care acesta este relaţional.
Un model relaţional este caracterizat de trei elemente:
• structura relaţională a datelor
• operatorii modelului relaţional
• regulile de integritate care guvernează folosirea cheilor în model.
Prezentarea structurii datelor impune definirea noţiunilor de domeniu, relaţie, schemă relaţională,
valoarea null şi tabel view. Un domeniu 4 este o mulţime de valori care poate fi definită fie enumerând
11

elementele componente, fie de3finind o proprietate distinctă a domeniului valorilor. Fie D1, D2, ......., Dn
domenii finite, nu neapărat disjuncte. Produsul cartezian D 1 x D2 x ......x Dn al domeniilor D1, D2, ...., Dn este
definit de mulţimea tuplurilor (V1,V2,.....,Vn) , unde V1є D1, …, Vn є Dn. O relaţie R pe mulţimile D1,
D2,....., Dn este o submulţime a produsului cartezian D1 x D2 x ......x Dn, deci o mulţime de tupluri. Relaţia
poate fi definită şi ca o mulţime finită de funcţii R = {f1, f2 ,...., fm} cu fj : {A1, A2,..., An} → D1 ∪ D2
∪ ....... ∪ Dn şi fj (Ai) є Di , în care asociem fiecărui domeniu Di un atribut Ai. Mulţimea numelor atributelor
corespunzătoare unei relaţii o numim schemă relaţională şi o notăm cu R (A1, A2,....., An). Putem reprezinta
o relaţie printr-un tabel bidimensional în care fiecare linie corespunde unui tuplu, iar fiecare coloană unui
domeniu din produsul cartezian, de fapt unui atribut. Numele atributului exprimă de obicei semnificaţia
valorilor din calcul coloanei respective. Numărul atributelor defineşte gradul relaţiei, iar numărul de tupluri
din relaţie defineşte cardinalitatea relaţiei.

FORMAL UZUAL FIZIC


relaţie tabel Fişier
tuplu linie Inregistrare
atribut coloană câmp
domeniu tip de dată tip de dată

Fig. 1.1 Concepte de bază

Atunci când inserăm tupluri într-o relaţie, de multe ori un atribut este necunoscut sau neaplicabil.
Pentru a reprezenta acest atribut a fost introdusă o valoare convenţională în relaţie, şi anume valoarea null.
În ceea ce priveşte un tabel de tip view (vizualizare, filtru, relaţie virtuală) acesta reprezintă o filtrare a
tabelului iniţial necesară unei anumite abordări, unei anumite aplicaţii. Spunem că un tabel de tip view
reprezintă o relaţie virtuală, deoarece datele pe care le conţine nu sunt în realitate memorate, fiind stocată
numai definiţia vizualizării. Utilizarea vizualizărilor este, în anumite situaţii, avantajoasă, asigurând
securitatea tabelului iniţial, care este astfel protejat de ştergeri, modificări, etc., dar prezintă şi limitări în
prelucrarea datelor.
Operatorii modelului relaţional definesc operaţiile care se pot efectua asupra relaţiilor, în scopul
realizării funcţiilor de prelucrare asupra bazei de date. Modelul relaţional oferă două mulţimi de operatori pe
relaţii şi anume: algebra relaţională şi calculul relaţional. Operatorii algebrei relaţionale sunt fie operatori
tradiţionali pe mulţimi (UNION, INTERSECT, PRODUCT, DIFFERENCE), fie operatori relaţionali
speciali (PROJECT, SELECT, JOIN, DIVISION). Calculul relaţional este de două tipuri : orientat pe tupluri
sau orientat pe domenii, reprezentând o adaptare a calculului predicatelor la domeniul bazelor de date. Pe
baza unor predicate iniţiale, prin aplicarea unor operatori ai calculului cu predicate (conjuncţia, disfuncţia,
4
negaţia, cuantificatorul existenţial şi cel universal) se pot defini noi predicate, noi relaţii. Conform
echivalenţei dintre algebra relaţională şi calculul relaţional demonstrate de Ullmann, orice relaţie posibil de
definit în algebra relaţională poate fi definită şi în cadrul calculului relaţional, şi reciproc.

3 3
Obs. Nu trebuie confundat termenul de relaţie (tabel) cu noţiunea de relaţie (asociere) introdusă în cadrul paragrafului
1.1.1

4
Popescu I., Baze de date relaţionale, Editura Universităţii din Bucureşti, 1996
12

Regulile de integritate sunt aserţiuni pe care datele conţinute în baza de date trebuie să le satisfacă.
Trebuie făcută distincţia între regulile structurale care sunt inerente modelării datelor şi regulile de
funcţionare (comportament) care sunt specifice unei aplicaţii particulare. Există trei tipuri de constângeri
structurale (de cheie, de referinţă, de entitate) ce constituie mulţimea minimală de reguli de integritate pe
care trebuie să le respecte un SGBD relaţional şi care sunt definite în raport cu noţiunea de cheie a unei
relaţii. O mulţime minimală de atribute ale căror valori identifică un tuplu unic într-o relaţie reprezintă o
cheie pentru relaţia respectivă. Fiecare relaţie are cel puţin o cheie de identificare. Dacă există mai multe
chei de identificare, atunci acestea se numesc chei candidat. Una dintre cheile candidat va fi aleasă de către
administratorul bazei de date pentru a identifica efectiv tupluri şi ea va primi numele de cheie primară, iar
celelalte chei candidat vor purta numele de chei alternative sau alternate. Modelul relaţional serveşte la
reprezentarea entităţilor din lumea reală şi a asocierilor dintre acestea. Modelarea asocierilor dintre entităţi
impune recurgerea la conceptul de cheie externă. Aceasta reprezintă un atribut/grup de atribute dintr-o
relaţie R1 ale cărui/căror valori sunt definite pe acelaşi domeniu/aceleaşi domenii ca şi cheia primară a unei
alte relaţii R2 şi care are rolul de a modela asocierea dintre entităţile reprezentate prin relaţiile R1 şi R2. În
acest context, R1 este denumită relaţie care referă, iar R2 poartă numele de relaţie referită.
Cu aceste considerente, cele trei reguli de integritate structurală se referă la :
• unicitatea cheii: cheia primară trebuie să fie unică şi minimală;
• integritatea entităţii: atributele cheii primare trebuie să fie diferite de valoarea null;
• integritatea referirii: o cheie externă trebuie ori să fie null în întregime, ori să corespundă la o
valoare a cheii primare asociate.

1.1.3 Caracteristicile unui SGBD relaţional


Deoarece regulile lui Codd sunt prea severe pentru a fi respectate de un SGBD relaţional, s-au
formulat criterii minimale de definire a unui sistem relaţional.
Un SGBD este minimal relaţional dacă satisface următoarele condiţii:
 Toate datele din cadrul bazei de date sunt reprezentate prin valori în tabele.
 Nu există pointeri observabili de către utilizatori.
 Sistemul suportă operatorii relaţionali de proiecţie, selecţie şi compunere naturală, fără
limitări impuse din considerente interne.
Un SGBD este complet relaţional dacă este minimal relaţional şi satisface în plus următoarele
condiţii:
 Sistemul suportă restricţiile de integritate de bază (unicitatea cheii primare, constrângerile de
referinţă, integritatea entităţii).
 Sistemul suportă toate operaţiile de bază ale algebrei relaţionale.
Un SGBD relaţional îndeplineşte funtiile unui SGBD, cu anumite particularităţi care decurg din
concepţia de organizare a datelor, respectiv din modelul relaţional. Fiecare SGBD relaţional implementează
modelul relaţional într-o manieră proprie care îl diferenţiază de restul sistemelor relaţionale.
Caracterizarea unui SGBD relaţional se poate realiza la nivelul clasei SGBD-urilor relaţionale, în
sensul caracterizării globale, unitare în raport cu celelalte tipuri de SGBD-uri, sau la nivelul unui SGBD
relaţional individual în sensul caracterizării particularităţilor sale, în raport cu alte SGBD-uri relaţionale.
Realizarea funcţiilor SGBD-urilor relaţionale se face cu ajutorul unor mecanisme de lucru specifice,
care le separă de sistemele nerelaţionale. Dintre instrumentele şi mecanismele de lucru de care dispune un
SGBD relaţional se disting:
 un limbaj relaţional pentru descrierea datelor la nivel fizic, logic şi conceptual;
 un limbaj relaţional pentru manipularea datelor;
13

 mecanisme pentru controlul integrităţii semantice a datelor;


 mecanisme pentru optimizarea cererilor de date;
 mecanisme pentru asigurarea coerenţei datelor în condiţiile accesului la date;
 utilitare pentru generarea de rapoarte şi de etichete, utilitare pentru generarea de aplicaţii,
utilitare pentru generarea unor statistici referitoare la starea şi activitatea bazei de date, etc.

1.1.4 Normalizarea relaţiilor


Codd a arătat că intr-o anumită formă relaţiile posedă proprietăţi nedorite, pe care le-a numit
anomalii de actualizare:
 anomalia de ştergere constă în faptul că anumite date care urmează să fie şterse, fac parte din
tupluri în care se găsesc şi alte date care mai sunt necesare în continuare, ori ştergerea făcându-se
la nivelul tuplului, acestea se pierd;
 anomalia de adăugare constă în faptul că anumite date care urmează să fie adăugate fac parte
din tupluri incomplete (pentru care nu se cunosc toate datele), ceea ce face ca acestea să nu poată
fi adăugate;
 anomalia de modificare rezultă din faptul că este dificil de modificat o valoare a unui atribut
atunci când ea apare în mai multe tupluri ale relaţiei.
Pentru a înlătura aceste anomalii, Codd a stabilit trei forme normale pentru relaţii şi a introdus
procesul de normalizare care se bazează pe noţiunea de dependenţă funcţională ca relaţie între atributele unei
entităţi ce are un caracter invariant.
Procesul de normalizare a relaţiilor se realizează în mai mulţi paşi, începând cu forma normală unu
(FN1) şi ajungând (după ultimele cercetări) la forma normală cinci (FN5). Teoria normalizării se ocupă cu
îmbunătăţirea succesivă a schemei conceptuale, find satisfăcute, în acelaşi timp, următoarele condiţii:
 conservarea datelor, adică în schema conceptuală finală să existe toate datele din cadrul schemei
iniţiale;
 conservarea dependenţelor dintre date, adică să se păstreze tipurile de relaţii dintre entităţi;
 descopunerea minimală a relaţiilor iniţiale, adică în schema conceptuală finală nici o relaţie nu
trebuie să fie conţinută într-alta.
O relaţie este în forma normală 1 (FN1), dacă şi numai dacă toate atributele ei conţin numai valori
atomice. În plus, un tuplu nu trebuie să conţină atribute sau grupuri de atribute repetitive. Este forma de bază
a relaţiilor, care figurează ca cerinţă minimală la majoritatea sistemelor de gestiune a bazelor de date
relaţionale.
O relaţie este în a doua formă normală FN2, dacă este în FN1 şi oricare dintre atributele non-cheie
este dependent funcţional complet de cheia primară a relaţiei.
O relaţie este în forma normală 3 (FN3), dacă se găseşte în FN2 şi toate atributele non-cheie sunt
dependente tranzitiv de cheia primară.
În afara acestor trei forme normale au fost introduse şi formele FNBC (forma normală Boyce –
Codd), FN4 şi FN5 care conduc la diminuarea redundanţei în baza de date. Trecerea de la forma FN3 la
FN4 şi FN5 se face operând asupra cheilor compuse între ale căror atribute apar relaţii care generează
dependenţe ce nu sunt funcţionale, numite dependenţe multi-valoare. O relaţie este în forma normală FNBC,
dacă fiecare determinant (acesta este un atribut sau o mulţime de atribute neredundante care constituie un
identificator unic pentru alt atribut sau altă mulţime de atribute ale unei relaţii) este o cheie candidat.
A patra formă normală FN4 elimină redundanţele datorate relaţiilor de tip n:m, iar a cincea formă
normală FN5 este mai mult „academică“ şi apare destul de rar în practică.
14

1.2. Crearea bazelor de date


În Visual FoxPro o bază de date are asociat un fişier special (.DBC) în care sunt memorate date
referitoare la baza de date în ansamblul ei, cum ar fi: tabelele componente, relaţiile permanente între tabele,
dicţionarul de date asociat bazei de date, etc. În acest fel, între date şi programele de prelucrare se interpune
un nou nivel, care asigură independenţa bazelor de date faţă de programele de prelucrare.
Un program care prelucrează o bază de date relaţională citeşte mai întâi informaţiile înscrise în fişierul
.DBC asociat acesteia şi numai apoi, după ce cunoaşte structura complexă a bazei de date, trece la
prelucrarea efectivă a datelor din tabele.
O dată cu introducerea în Visual FoxPro a noului concept de bază de date, o tabelă clasică a fost
îmbunătăţită cu o serie de caracteristici suplimentare, care sunt disponibile numai dacă tabela respectivă este
inclusă într-o bază de date. Aceste facilităţi suplimentare se manifestă la nivelul câmpurilor componente sau
la nivelul tabelei în ansamblul ei. Prin urmare, în Visual FoxPro se disting două tipuri de tabele:
♦ cele clasice, simple (din versiunile FoxPro pentru DOS şi WINDOWS)
♦ cele incluse în baze de date (tipice pentru Visual FoxPro).
În vederea construirii unei baze de date trebuie parcurşi următorii paşi:
• mai întâi se construieşte un fişier bază de date nou, în care vor fi memorate datele referitoare la
baza de date şi la tabelele componente;
• apoi se încorporează pe rând tabelele simple create anterior sau se construiesc tabele noi, direct
încorporate în noua bază de date;
• pentru tabele simple urmează specificarea acelor caracteristici noi, care nu se puteau declara la
construirea lor ca tabele izolate;
• se stabilesc legăturile, relaţiile între tabele;
• se pot preciza o serie de caracteristici noi ale bazei de date în ansamblul ei;
• se pot construi şi incorpora în baza de date o serie de elemente speciale, precum vederile,
conexiunile, etc.
15

Fig. 1.2 Crearea unei baze de date. Definirea structurii unei tabele componente

1.2.1 Stabilirea structurii unui tabel şi a caracteristicilor


acestuia
Fiecare câmp al unei tabele este caracterizat prin:
• nume (Name): reprezintă identificatorul prin care se face referire la câmpul respectiv, la datele
memorate în acesta;
• tip (Type): tipul datelor care pot fi memorate în câmpul respectiv; acesta poate fi: şir de
caractere, numeric de diferite feluri, dată calendaristică sau moment de timp, logic, „memo”, sau
„general”:
• lungime (Width): reprezintă numărul de caractere pe care îl ocupă fiecare dată memorată în
câmpul respectiv;
• numărul de zecimale (Decimal): caracteristică valabilă în cazul câmpurilor numerice, care
indică numărul de cifre de după punctul zecimal memorate în câmp; lungimea câmpului,
precizată anterior, trebuie să includă şi această valoare precum şi punctul zecimal propriu-zis;
• fanionul de indexare (Index): indică dacă se stabileşte un index pe baza câmpului respectiv;
poziţionarea acestui indicator implică stabilirea câmpului ca şi cheie de indexare şi determină
crearea unui tag (etichetă index) cu acelaşi nume ca şi câmpul, în cadrul fişierului index
structural asociat tabelei;
• fanionul de valoare nulă (NULL): arată dacă în câmpul respectiv poate fi memorată sau nu o
valoare nulă; această caracteristică a fost introdusă datorită necesităţii diferenţierii între un câmp
lăsat necompletat de utilizator şi unul completat cu valoarea 0.

TIP CÂMP VALORI ADMISE


Character şiruri de caractere cu lungime între 1 şi 254 caractere
Familia tipurilor numere întregi sau reale:
numerice - Integer (4 octeţi): valori întregi din intervalul
[-2147483647, +2147483646];
- Double (8 octeţi): valori reale în dublă precizie din intervalele
[-4.94065645841247·10-324, +4.94065645841247·10-324]
[–8.9884656743115 ·10307, +8. 9884656743115 ·10307]
- Numeric şi Float: tipuri numerice standard; zona de memorie
alocată pentru un câmp de acest tip este dependentă de lungimea
declarată de utilizator la crearea tabelei respective (de la 1 la 20
de octeţi); pentru fiecare cifră sistemul alocă în tabelă 1 octet; se
pot reprezenta valori din intervalul
[– 0.9999999999 ·1019, 0.9999999999·1020]
Currency tipul monetar folosit pentru memorarea valorilor exprimate în bani; zona
de memorie alocată are dimensiunea de 8 octeţi; valorile de acest tip
trebuie să se încadreze în intervalul
[– 922337203685477.5808 , 922337203685477.5807]
Logical valori logice (1 octet)
Date valori de tip dată calendaristică (8 octeţi)
DataTime valori de tip dată calendaristică urmate de marci de timp (8 octeţi)
General acest tip de date permite memorarea în tabele a unor elemente create cu
ajutorul altor programe, cum ar fi documente, foi de calcul tabelar,
imagini, etc., utilizându-se tehnologia OLE de incorporare şi de legare a
obiectelor (4 octeţi)
16

Memo acest tip de date se foloseşte pentru prelucrarea textelor, adică a şirurilor
de caractere de dimensiuni mari sau variabile, în câmpul de tip „memo”
memorându-se un indicator spre textul salvat într-un fişier distinct de
tipul .FTP (4 octeţi)

Pe lângă aceste caracteristici, pentru tabele incluse într-o bază de date se pot efectua şi următoarele
precizări pentru câmpurile din structura lor:
• pentru fiecare câmp se poate stabili un format implicit de afişare a datelor (Display → Format);
• pentru fiecare câmp în parte se poate stabili o machetă pentru introducerea datelor (Display →
Input Mask);
• se poate stabili un titlu nou pentru fiecare câmp; acesta va apare în antetul vizualizării
conţinutului tabelei (Display → Caption);
• o valoare iniţială implicită pentru fiecare câmp; la adăugării unei noi înregistrări, câmpurile
acesteia vor fi iniţializate cu aceste valori implicite (Field Validation → Default value);
• pentru fiecare câmp se poate impune o regulă de validare a valorilor (Field Validation → Rule)
şi eventual un mesaj care să fie afişat pe ecran în cazul nerespectării condiţiei de validare impuse
(Field Validation → Message); regula de validare la nivel de câmp constă dintr-o expresie
logică, ce va fi evaluată la orice modificare a valorii câmpului respectiv; dacă valoarea rezultată
în urma evaluării expresiei de validare este false, atunci noua valoare a câmpului nu va fi
acceptată şi se va afişa un mesaj de eroare standard sau unul specificat de utilizator.
La nivelul tabelei în ansamblu (figura 1.3), pot fi precizate: o regulă de validare la nivel de
înregistrare (la modificarea unei înregistrări) şi, eventual, un mesaj de eroare, în cazul nerespectării acestei
reguli, precum şi secvenţe de cod care să fie executate la inserarea unei noi înregistrări, la actualizarea
(modificarea) sau la ştergerea uneia existente. Validarea la nivel de înregistrare (Record Validation → Rule)
se declanşează după cea la nivel de câmp, dar înaintea secvenţelor de cod asociate evenimentelor de
manipulare a tabelei.

Fig. 1.3 Facilităţi suplimentare la nivelul unei tabele în ansamblul ei


17

Adăugarea unei înregistrări, modificarea datelor dintr-o înregistrare existentă precum şi ştergerea unei
înregistrări a tabelei constituie trei evenimente de manipulare a datelor dintr-o tabelă inclusă într-o bază de
date. Pentru fiecare dintre aceste evenimente se poate specifica câte o secvenţă de cod care să fie executată la
apariţia acestuia. Secvenţele de cod asociate evenimentelor de manipulare a unei tabele se declanşează după
validările la nivel de câmp şi la nivel de înregistrare.

1.2.2 Indexarea tabelelor


Indexarea reprezintă o tehnică de ordonare logică a datelor dintr-o tabelă, după diferite criterii,
operaţie care însă nu afectează ordinea fizică a datelor din tabelă, ci doar modul în care acestea sunt văzute
de utilizator.
Ordonarea unei tabele presupune stabilirea unui criteriu după care să fie parcurse înregistrările ei.
Acest criteriu poate fi un câmp sau o combinaţie de câmpuri ale tabelei. Criteriul de ordonare reprezintă de
fapt o expresie, numită cheie de ordonare sau de indexare, în alcătuirea căreia intră câmpuri ale tabelei.
Pentru stabilirea ordinii înregistrărilor tabelei se evaluează expresia cheii de ordonare pentru fiecare
înregistrare în parte, valorile obţinute se compară între ele, iar ordinea înregistrărilor în tabelă se stabileşte în
funcţie de rezultatul obţinut.
Există două tipuri de ordonări ale unei tabele:
• fizică, numită şi sortare, ce constă în rearanjarea fizică a datelor din tabelă într-o altă ordine,
dată de criteriul respectiv; în urma sortării rezultă o nouă tabelă, cu aceeaşi structură ca şi cea de
bază, dar cu înregistrările aranjate în ordinea dorită;
• logică, numită şi indexare, care constă în construirea unui fişier special, folosit la regăsirea
datelor din tabelă în ordinea dorită; prin indexare, ordinea fizică a înregistrărilor din tabelă nu se
modifică, se schimbă însă modul în care utilizatorul are acces la datele acesteia.
În mod simplificat, putem considera tabela index formată din cheia de indexare şi un număr de
înregistrare (pointer) din tabela de date.
Fie tabela “date_pers” din figura nr. 1.2 pentru care s-a stabilit câmpul “nr_leg” ca şi cheie de
indexare. Pe baza valorilor, în ordine crescătoare, a acesteia, s-a construit tag-ul (eticheta index) “nr_leg” al
fişierului index structural “date_pers.CDX” asociat tabelei. “Prima” înregistrare a tabelei indexate o
constituie cea corespunzătoare celei mai mici valori a cheii de indexare, iar “ultima” înregistrare a fişierului
indexat este cea care conţine cea mai mare valoare a cheii de indexare (figura 1.4).
O tabelă poate avea mai mulţi indecşi asociaţi, dar numai unul singur va fi activ la un moment dat.
Ordinea în care va fi parcursă tabela este dată de indexul activ.
În Visual FoxPro, prin indexarea unei tabele, se crează în mod automat o etichetă index în cadrul
fişierul index structural asociat tabelei (.CDX). Prin comenzi explicite de indexare, se poate solicita crearea
unui index simplu (.IDX) sau a unui index compus nestructural (memorat într-un fişier de tipul .CDX având
însă un nume diferit de cel al tabelei care se indexează). Un index poate fi considerat un filtru aplicat tabelei,
filtru prin care datele respective sunt pribite într-o anumită ordine. Văzuţi din această perspectivă, indecşii
pot chiar anula accesul la unele înregistrări ale tabelei.
Un tip special de filtrare prin indexare este acela al înregistrărilor cu aceeaşi valoare a cheii de
indexare. Din acest punct de vedere, indecşii pot fi de două feluri:
• normali (Regular), care construiesc pentru fiecare înregistrare a tabelei câte o
înregistrare în fişierul index respectiv, indiferent de duplicarea (sau multiplicarea) valorii cheii
de indexare; prin urmare, într-o astfel de tabelă indexată toate înregistrările sunt accesibile,
indiferent de valoarea cheii de indexare;
• unici (Unique), care permit o unică valoare a cheii de indexare; dacă două sau mai
multe înregistrări ale tabelei corespund aceleiaşi valori a cheii de indexare, numai prima
dintre acestea va fi disponibilă (accesibilă), restul neapărând în tabelă (deşi fizic există).
18

Fig. 1.4 Localizarea, în acces direct, a înregistrării ce conţine în nr_leg valoarea 1005

Legarea tabelelor între ele în cadrul modelului relaţional a impus alte două tipuri de indecşi,
cel candidat şi cel cheie:
• indexul candidat în cadrul unei tabele pot exista mai multe câmpuri (sau mai precis mai multe
criterii) care să asigure identificarea unică a înregistrărilor tabelei şi care vor sta la baza definirii
indexilor de acest tip; spre deosebire de indexul unic, cel candidat va împiedeca încărcarea într-o
înregistrare a unor valori care, după evaluarea cheii de indexare, conduc la valori existente în
tabelă;
• indexul de tip cheie primară: se va alege dintre potenţialii indecsi de tip candidat şi va juca un
rol important în legarea tabelelor.
Tipurile de indecşi prezentate (normali, unici, candidaţi şi de tip cheie primară) impun anumite
restricţii de acces, în funcţie de valorile cheii de indexare. Accesul la înregistrările tabelei este din ce în ce
mai restrictiv, în ordinea: indecşi normali, unici, candidat sau de tip cheie primară.

1.2.3 Relaţii între tabele


Modelul relaţional al bazelor de date implică organizarea datelor în tabele legate între ele prin relaţii.
Scopul stabilirii relaţiilor este acela de coordonare, după diferite criterii, a datelor citite din tabelele aflate în
legătură. Fie două tabele T1 şi T2, A un câmp din primul tabel şi B un câmp din cel de-al doilea tabel, cele
două câmpuri având valori de acelaşi tip. Tabelul T1 se va numi tabel primar (principal), iat T2 tabel referit
(secundar) 5. Unei înregistrări din T1, cu valoarea V în câmpul A, i se pot pune în corespondenţă anumite
înregistrări din tabela T2. Câmpul A din tabela T1 se numeşte cheie externă, deoarece valorile sale se vor
căuta în T2, printre valorile câmpului B.

5
Lupulescu M., Muntean M., Dănăiaţă D., Medii de programare, Editura Mirton, Timişoara, 2000
19

Fig. 1.5 Definirea unei relaţii între două tabele

Cu ajutorul câmpurilor A şi B, legătura dintre tabelele T1 şi T2 poate fi unul dintre următoarele trei
tipuri:
• 1:1 (one-to-one): unei valori V din câmpul A îi corespunde o unică valoare din câmpul B;
• 1:n (one-to-many): unei valori V din câmpul A îi corespund mai multe valori din câmpul B;
• n:1 (many-to-one): unei valori V din câmpul B îi corespund mai multe valori din câmpul A;
• m:n (many-to-many): unei valori din câmpul A, ce se regăseşte în mai multe înregistrări ale
tabelei T1, îi corespund mai multe valori din câmpul B.
Dintre acestea, în Visual FoxPro sunt implementate doar primele trei tipuri de relaţii. Lipsesc relaţiile
de tipul m:n, deoarece ele se pot reduce la două relaţii, una de tipul n:1 şi alta de tipul 1:n prin intermediul
unor tabele suplimentare intercalate între primele două.
Un alt criteriu de clasificare a relaţiilor dintre tabele este cel al momentului definirii lor. Din acest
punct de vedere există:
• relaţii temporare sau dinamice, care sunt create prin comenzi introduse în programele de
prelucrare, deci sunt disponibile numai la rularea acestora. În afara programelor de prelucrare,
relaţiile respective nu există;
• relaţii permanante, care sunt create automat de sistem la deschiderea bazei de date care conţine
tabelele legate; aceste relaţii sunt disponibile imediat ce este deschisă baza de date, deoarece
sunt memorate în fişierul bazei de date.
La crearea unei relaţii permanente între două tabele este necesară îndeplinirea unor condiţii
prealabile şi anume:
• tabelul primar trebuie să fie indexat cu un index candidat sau primar;
• tabelul referit poate fi indexat cu orice fel de index, de acesta depinzând însă tipul relaţiei
definite.
Condiţia indexării tabelului primar cu un index candidat sau primar determină stabilirea numai a unor
relaţii permanente de tip 1:1 sau 1:n, deoarece acest tip de index împiedică existenţa, în tabelul primar, a
mai multor înregistrări cu aceeaşi valoare a cheii de indexare. Dacă dorim crearea unei relaţii de tip n:1,
aceasta trebuie văzută dinspre tabelul referit înspre tabelul primar. Desigur că prin aceasta se inversează
rolurile primar – referit între tabele. Dacă dorim neapărat ca tabelul primar să-şi păstreze acest rol pentru o
altă relaţie, se poate crea o vedere (view) din cele două tabele legate, vedere care va deveni noul tabel primar
pentru relaţia respectivă.
În esenţă, legătura între două tabele constă într-un cậmp comun ce există în ambele tabele. În felul
acesta se leagă o înregistrare din primul tabel de (prima) înregistrarea corespunzătoare din tabelul referit,
adică legătura se stabileşte pe baza unor valori egale în cậmpul de legătură.
20

Fig. 1.6 Definirea relaţiilor permanente

1.2.4 Integritatea referenţială a tabelelor legate între ele


prin relaţii
Integritatea referenţială reprezintă un ansamblu de reguli impuse tabelelor între care s-au stabilit
relaţii. Aceste reguli sunt necesare deoarece deseori se doreşte modificarea unor date dintr-o tabelă, date care
afectează relaţia dintre această tabelă şi o alta.
Printre evenimentele care conduc la modificări ale cheii şi deci reprezintă evenimente ce trebuie
tratate prin integritatea referenţială se numără următoarele 6:
• adăugarea unei înregistrări noi;
• ştergerea unei înregistrări;
• modificarea datelor unei înregistrări, date care afectează relaţia.
În cazul adăugării unei noi înregistrări în tabelul referit printr-o relaţie, există următoarele
opţiuni:
• ignorare (Ignore) – cu alte cuvinte, se permite adăugarea noii înregistrări în tabelul referit,
indiferent dacă există sau nu o înregistrare corespunzătoare în tabelul primar;
• restricţionare (Restrict) – se generează o eroare atunci când se încearcă adăugarea unui
înregistrări în tabelul referit printr-o relaţie, fără corespondent în tabelul primar.

6
Muntean M., Baze de date în sisteme informatice, Editura Mirton, Timişoara, 2002
21

Fig. 1.7 Adăugarea unei noi înregistrări în tabela copil a unei relaţii

Ştergerea unei înregistrări din tabelul primar al unei relaţii este de asemenea gestionată prin
intermediul integrităţii referenţiale. În acest caz, avem la dispoziţie următoarele opţiuni:
• ignorare (Ignore) – se permite această ştergere, indiferent dacă în tabelul referit există sau nu
înregistrări legate de înregistrarea primară ştearsă;
• restricţionare (Restrict) – opreşte ştergerea, generând un mesaj de eroare, atunci când există
înregistrări corespunzătoare în tabela referită;
• ştergere în cascadă (Cascade) – se şterg automat toate înregistrările din tabelul referit legate de
înregistrarea primară ştearsă.
Modificarea unor date din tabelul primar, ce afectează relaţia dintre tabele, este de asemenea tratată
prin regulile integrităţii referenţiale în felul următor:
• ignorare (Ignore) – se permit modificările respective, chiar dacă prin aceasta înregistrările
referite corespunzătoare rămân „în aer“, adică fără corespondent în tabelul primar;
• restricţionare (Restrict) – atunci când există înregistrări corespunzătoare în tabela referită,
modificarea este oprită şi este generat un mesaj de eroare;
• modificare în cascadă (Cascade) – sunt modificate automat toate înregistrările din tabelul
referit conform noii valori a cheii relaţiei.

1.2.5 Crearea prin intermediul limbajului Visual FoxPro a


unei BD
1. Crearea bazei de date de tip .DBC

CREATE DATABASE <bază_de_date>

2. Crearea tabelelor, a indecşilor şi a relaţiilor permanente dintre tabele

CREATE TABLE | DBF <tabelă1>


(<câmp1> <tip> (<lungime> [, <zecimale>])
[NULL | NOT NULL]
[CHECK <expl1> [ERROR <text1>]]
[DEFAULT <expr2>]
[PRIMARY KEY | UNIQUE]
22

[REFERENCES <tabelă2> [TAG <etichetă_index1>]]


[, <câmp2> ...]
[, PRIMARY KEY <expr3> TAG <etichetă_index2>
|, UNIQUE <expr4> TAG <etichetă_index3>]
[, FOREIGN KEY <expr5> TAG <etichetă_index4> [NODUP]
REFERENCES <tabelă3> [TAG <etichetă_index5>]])
| FROM ARRAY <tablou>

În cadrul bazei de date curent deschise, <bază_de_date> se va crea tabela <tabelă1>. Aceasta va
conţine câmpurile <câmp1>, <câmp2>, ...<câmpn>. Fiecărui câmp i se vor preciza tipul <tip>, lungimea
<lungime> şi dacă este cazul numărul de zecimale <zecimale>.
Pentru ca într-un câmp să poată fi memorată o valoare nulă, se va apela la argumentul NULL din
sintaxa generală a comenzii. Împiedicarea acestui lucru se va face specificând clauza NOT NULL pentru
câmpul respectiv. În absenţa acestor specificări, câmpul se va comporta conform setării curente stabilite prin
comanda SET NULL ON | OFF. Pentru fiecare câmp se poate impune o regulă de validare a valorilor
acestora – CHECK <expl1>. Dacă condiţia <expl1> nu permite existenţa unui câmp necompletat, atunci
adăugarea unei înregistrări vide (de exemplu prin comanda APPEND BLANK) nu va fi posibilă şi va fi
generat un mesaj de eroare. Acest mesaj de eroare poate fi stabilit de către programator prin intermediul
clauzei ERROR <text1> (ERROR <text2>).
De asemenea, pentru fiecare câmp poate fi stabilită o valoare iniţială implicită – DEFAULT <expr2>,
la adăugarea unui noi înregistrări, câmpurile acesteia vor fi iniţializate cu valorile implicite specificate.
Dacă se doreşte definirea unui index de tip cheie primară, atunci se va apela la clauza PRIMARY KEY
în definirea câmpului ale cărui valori vor sta la baza generării indexului. Acesta va avea acelaşi nume ca şi
câmpul.
Se poate defini un index unic pe baza valorilor unui câmp al tabelei (UNIQUE), acesta va face ca
numai prima dintre înregistrările ce conţin aceeaşi valoare a cheii de indexare să fie accesibilă.
Tabela <tabelă1> creată prin comanda CREATE TABLE | DBF poate constitui un tabel referit într-o
relaţie permanentă, al cărei tabel primar se specifică prin <tabelă 2>. Revenind la figura 1.5, câmpul B este
cel căruia i s-a ataşat clauza REFERENCE <tabelă2>, iar câmpul A din tabelul primar, este cel pe baza
valorilor căruia s-a construit indexul <etichetă_index1>. În absenţa clauzei TAG <etichetă_index1> se ia în
considerare indexul de tip cheie primară al tabelului primar <tabelă2>.
Odată cu creerea tabelei <tabelă1> se poate defini şi un index de tip cheie primară al acesteia, ce are
are la bază o combinaţie de câmpuri ale tabelei şi care va asigura identificarea unică a înregistrărilor tabelei.
Cu valorile lui <expr3>, reprezentând combinaţia de câmpuri dorită, se va forma <etichetă_index2>. Clauza
PRIMARY KEY <expr3> TAG <etichetă_index2> nu va putea fi folosită, dacă s-a definit deja un index de
tip cheie primară cu valorile unui câmp (clauza PRIMARY KEY ataşată câmpului respectiv). Reamintim, că
o tabelă poate avea un singur index de tip cheie primară. Clauza UNIQUE <expr4> TAG <etichetă_index3>
crează un index candidat pe baza valorilor lui <expr4>, ce reprezintă un câmp sau o combinaţie de câmpuri
din tabela nou creată. Trebuie menţionat că, câmpul/câmpurile pe baza căruia/cărora s-a construit indexul de
tip cheie primară nu poate/pot apare în <expr4>. De asemenea, o tabelă poate avea mai mulţi indecşi de tip
candidat.
Clauza FOREIGN KEY <expr5> TAG <etichetă_index4> [NODUP] permite definirea unui index
normal (regular) <etichetă_index4>, pe baza valorilor cheii de indexare <expr5>, pentru tabela <tabelă1>,
fiind esenţială în stabilirea unei relaţii de tipul 1:n cu tabela primară <tabelă3>. Dacă se include specificarea
NODUP în clauză, se va creea un index de tip candidat pentru <tabelă1>, ce va constitui tabelul referit din
relaţia stabilită cu tabela primară <tabelă3>. Noua tabelă <tabelă1> poate fi creată şi cu ajutorul unui tablou,
ce conţine numele, tipul, lungimea şi precizia pentru fiecare câmp al tabelei. Conţinutul lui <tablou> va fi
stabilit în prealabil cu ajutorul funcţiei AFIELDS( ).
Considerând situaţia prezentată în figura 1.6, la nivel de comenzi Visual FoxPro, avem următoarele:

CREATE DATABASE studenti


23

CREATE TABLE date_pers ;


(nr_leg N(6) PRIMARY KEY, nume C(35), prenume C(35), adresa C(50))
CREATE TABLE anul1 (nr_leg N(6) PRIMARY KEY REFERENCES date_pers, ;
nota1 N(2), nota2 N(2), nota3 N(2), nota4 N(2), nota5 N(2))
CREATE TABLE anul2 (nr_leg N(6) PRIMARY KEY REFERENCES date_pers, ;
nota1 N(2), nota2 N(2), nota3 N(2), nota4 N(2), nota5 N(2))
CREATE TABLE anul3 (nr_leg N(6) PRIMARY KEY REFERENCES date_pers, ;
nota1 N(2), nota2 N(2), nota3 N(2), nota4 N(2), nota5 N(2))
CREATE TABLE anul4 (nr_leg N(6) PRIMARY KEY REFERENCES date_pers, ;
nota1 N(2), nota2 N(2), nota3 N(2), nota4 N(2), nota5 N(2))
Considerăm situaţia din figura 1.8, căreia îi va corespunde următoarea secvenţă de comenzi :

Fig. 1.8 Relaţie permanentă de tipul 1:n

CREATE DATABASE conta


CREATE TABLE conturi (simbol N(8) PRIMARY KEY, ;
tip C(1) CHECK tip="A" OR tip="P" DEFAULT "A", ;
soldi N(10), debit N(10), credit N(10), soldf N(10))
CREATE TABLE operatii (simbol N(8), data_op D(8) DEFAULT { / / }, ;
tip_op C(1) CHECK tip_op="D" OR tip_op="C" DEFAULT "D", ;
valoare N(10), ;
FOREIGN KEY simbol TAG simbol REFERENCES conturi)
CLOSE TABLES
CLOSE DATABASES

Baza de date <conta> conţine tabelele <conturi> şi <operatii>, între care s-a definit o relaţie de
tipul 1:n pe baza valorilor câmpului <simbol> ce apare în ambele tabele. Ambele tabele sunt indexate după
câmpul <simbol>, pentru tabela primară s-a generat o etichetă index de tip cheie primară, iar pentru tabelul
referit s-a creat un index normal (Regular), în conformitate cu tipul relaţiei 1:n.
Odată creată tabela <tabela1>, se poate apela la comenzile COPY STRUCTURE EXTENDED TO şi
CREATE …FROM pentru a crea o nouă tabelă, <tabela2>, cu o structură identică, utilizậnd următoarea
secvenţă de comenzi :
24

USE <tabela1>
COPY STRUCTURE EXTENDED TO <tabelă_structură>
CREATE <tabela2> FROM <tabelă_structură>

3. Posibilităţi de indexare ulterioară creării tabelei

INDEX ON <expr> TAG <etichetă_index>


[UNIQUE | CANDIDATE] [ASCENDING | DESCENDING]

Comanda INDEX ON nu permite definirea unui index de tip cheie primară, foarte important în
problemele ce vizează integritatea referenţială a tabelelor legate între ele prin relaţii. Pe baza valorilor lui
<expr>, care poate reprezenta un câmp sau o combinaţie de câmpuri ale tabelei curent deschise, se poate
genera o <etichetă_index>, în cadrul indexului structural ataşat tabelei (.CDX), de tip unic sau candidat.

4. Activarea unui index


O tabelă poate avea mai mulţi indecşi asociaţi (etichete index), dar numai unul va fi activ la un
moment dat. Ordinea în care va fi parcursă tabela este dată de indexul activ.

SET INDEX TO <etichetă_index> [ASCENDING | DESCENDING]

5. Definiri ulterioare de relaţii temporare între tabele


Relaţiile temporare sau dinamice sunt create prin comenzi introduse în programele de prelucrare, fiind
disponibile numai la rularea acestora. În afara programelor de prelucrare, aceste relaţii nu există. Printr-o
relaţie temporară pot fi legate atât două tabele ce fac parte dintr-o bază de date, cât şi tabele independente.
Spre deosebire de relaţiile permanente între tabele legate, cele temporare nu sunt memorate în baza de
date .DBC.
Pentru stabilirea unei relaţii temporare între două tabele oarecare, acestea trebuie mai întâi deschise în
două zone de lucru distincte. Relaţia stabilită între cele două tabele nu este o relaţie de egalitate, ci una de
subordonare: una dintre tabele va fi primară (părinte), iar cealaltă referită (copil). Mutarea indicatorului de
înregistrări al tabelei părinte pe o anumită înregistrare determină mutarea indicatorului de înregistrări al
tabelei copil pe înregistrarea corespunzătoare, dar nu şi invers.
Înainte de stabilirea relaţiei, pe lângă deschiderea celor două tabele mai trebuie îndeplinită o condiţie,
şi anume indexarea tabelei copil cu aceeaşi cheie de indexare cu cea a relaţiei.

OPEN DATABASE <bază_de_date>


USE <tabelă1> ORDER <etichetă_indexA> IN 1
USE <tabelă2> ORDER <etichetă_indexB> IN 2
SELECT 1
SET RELATION TO <câmpA> INTO 2
SET SKIP TO <tabela2>
< prelucrări >
SET SKIP TO
SET RELATION TO
CLOSE TABLES
CLOSE DATABASES
25

<câmpA> face parte din structura tabelului primar <tabelă1>, iar valorile sale se vor căuta printre
valorile câmpului <câmpB> din tabela referită <tabelă2>. Pe baza valorilor din <câmpB> s-a definit indexul
<etichetă_indexB>. Cu aceste considerente, se poate defini o relaţie temporară între <tabelă1> şi <tabelă2>
conform grupului de comenzi Visual FoxPro de mai sus. Relaţia dintre cele două tabele funcţionează în
modul următor: mutarea indicatorului de înregistrări din tabelul primar determină evaluarea succesivă a lui
<câmpA>. În funcţie de valorile acestuia, indicatorul de înregistrări al tabelului referit se va plasa pe prima
înregistrare pentru care valoare (<câmpB>) = valoare (<câmpA>).
Exemplificând această metodologie pentru baza de date din figura 1.8, vom obţine următoarea
secvenţă de comenzi :

OPEN DATABASE conta


USE conturi ORDER simbol IN 1
USE operatii ORDER simbol IN 2
SELECT 1
SET RELATION TO simbol INTO 2
SET SKIP TO operatii
<prelucrări >
SET SKIP TO
SET RELATION TO
CLOSE TABLES
CLOSE DATABASES

1.3. Modificarea structurii tabelelor


Modificarea structurii unei tabele se poate efectua în mod interactiv cu ajutorul comenzii MODIFY
STRUCTURE sau prin intermediul comenzii SQL ALTER TABLE.
Prima comandă activează fereastra Table Designer (figura 1.2), în cadrul căreia se vizualizează
structura tabelei precizate prin comandă.
MODIFY STRUCTURE <tabelă>
În cadrul acestei ferestre se pot adăuga sau şterge cậmpuri şi se pot modifica cele existente din punct
de vedere al numelui, tipului şi mărimii. Totodată se poate interveni asupra indecsilor existenţi precum şi
asupra restricţiilor impuse tabelei.
În ceea ce priveşte comanda SQL ALTER TABLE trebuie făcute următoarele precizări:

1. Adăugarea unui nou atribut


ALTER TABLE <tabelă1>
ADD [COLUMN] <câmp1> <tip> (<lungime> [, <zecimale>])
[NULL | NOT NULL]
[CHECK <expl1> [ERROR <text1>]]
[DEFAULT <expr2>]
[PRIMARY KEY | UNIQUE]
[REFERENCES <tabelă2> [TAG <etichetă_index1>]]
Se va modifica structura tabelei specificate prin <tabelă1> prin adăugarea cậmpului <cậmp1>.
Acesta va prezenta caracteristicile definite prin clauzele ataşate lui în sintaza comenzii.

2. Ştergerea unui atribut


ALTER TABLE <tabelă1>
DROP [COLUMN] <câmp1>
26

Nucleul SQL din Visual FoxPro, spre deosebire de alte sisteme de gestiune a bazelor de date
relationale, prevede posibilitatea de ştergere a unui cậmp din structura unei tabele.

6. Modificarea numelui/tipului/dimensiunii unui atribut


ALTER TABLE <tabelă1>
RENAME COLUMN <cậmp1_vechi> TO <cậmp1_nou>

ALTER TABLE <tabelă1>


ALTER [COLUMN] <câmp1> <tip> (<lungime> [, <zecimale>])

Este permisă modificarea tipului oricărui cậmp din structura unei tabele. Dacă cậmpul conţine
valori, se va încerca conversia acestora în conformitate cu noul tip stabilit pentru cậmp. În cazul unei
incompatibilităţi între noul tip şi vechiul tip al cậmpului, informaţia din cậmpul supus modificării de tip se
va pierde. Nu este recomandată modificarea tipului cậmpurilor de tip cheie primară sau candidat.
În ceea ce priveşte lungimea cậmpurilor, acestea pot fi deopotrivă mărite sau micşorate, la
micşorare trebuie avută însă în vedere trunchierea ce operează inevitabil.

7. Adăugarea/modificarea/anularea valorii implicite


ALTER TABLE <tabelă1>
ALTER [COLUMN] <câmp1> SET DEFAULT <expr1>
ALTER TABLE <tabelă1>
ALTER [COLUMN] <câmp1> DROP DEFAULT

8. NULL şi neNULL
Pentru unele atribute poate fi instituită la crearea tabelei obligativitatea valorilor nenule. În timp,
aceasta poate fi modificată într-un sens sau în celălalt.

ALTER TABLE <tabelă1>


ALTER [COLUMN] <câmp1> NULL | NOT NULL

9. Adăugarea/anularea restricţiilor
Restricţiile de tip cheie primară (PRIMARY KEY), de unicitate (UNIQUE), referenţială (FOREIGN
KEY) şi de comportament (CHECK) pot fi declarate ulterior creării tabelei sau pot fi anulate.
• Stabilirea unei chei primare şi crearea indexului corespunzător
ALTER TABLE <tabelă1>
ADD PRIMARY KEY <expr1> TAG <etichetă_index1>

• Anularea cheii primare şi a indexului aferent acesteia


ALTER TABLE <tabelă1>
DROP PRIMARY KEY

• Adăugarea unui index candidat


ALTER TABLE <tabelă1>
ADD UNIQUE <expr1> TAG <etichetă_index1>

• Anularea unui index candidat


27

ALTER TABLE <tabelă1>


DROP UNIQUE TAG <etichetă_index1>

• Stabilirea unei noi restricţii de validare pentru un cậmp


ALTER TABLE <tabelă1>
ALTER [COLUMN] <câmp1>
ADD CHECK <expl1> [ERROR <text1>]

• Anularea restricţiei de validare stabilite pentru un cậmp


ALTER TABLE <tabelă1>
ALTER [COLUMN] <câmp1>
DROP CHECK

• Adăugarea unei relaţii permanente


ALTER TABLE <tabelă1>
ADD FOREIGN KEY <expr1> TAG <etichetă_index1>
REFERENCES <tabelă2> [TAG <etichetă_index2>]
• Anularea unei relaţii permanente
ALTER TABLE <tabelă1>
DROP FOREIGN KEY TAG <etichetă_index1>

1.4 Utilizarea macrosubstituţiei în referirea


tabelelor şi a câmpurilor acestora
Macrosubstituţia permite printr-un mecanism de adresare indirectă referirea dinamică, în timpul
execuţiei comenzii, a unei tabele sau a unui cậmp al acesteia.
În figura 1.9 se propune o bază de date şi o procedură de evidenţă a intrărilor/ieşirilor de material
cât şi a stocului curent. Materialul se specifică cu ajutorul unui control de tip ComboBox legat de cậmpul
"cod" al tabelei "stocuri". Se vor seta corespunzător valorile proprietăţilor ControlSource (stocuri.cod),
RowSource Type (6-Fields) şi RowSource (stocuri.cod) ale controlului. Luarea în gestiune a unui nou
material (tastarea unui nou cod în zona de editare a combobox-ului) implică crearea unei noi tabele
corespunzător setărilor din forma de introducere.

procedura – frmmain_Activate
open database gest_mat
use stocuri order cod alias stocuri in 1
procedura – cmdInregistrare_Click
mat = val (thisform.cbocod.text)
if thisform.optiongroup1.option1.value = 1
nume_tabela = rtrim(thisform.cbocod.text) + "_Intrari.dbf"
cantitate = "Intrare"
else
nume_tabela = rtrim(thisform.cbocod.text) + "_Iesiri.dbf"
cantitate = "Iesire"
endif
if not file ((nume_tabela))
create table &nume_tabela (cod_mat N(10), data_op D(8) default { / / },;
&cantitate N(10), foreign key cod_mat tag cod_mat references stocuri)
28

use
select 1
seek mat
if not found( )
append blank
replace cod with mat
endif
endif
select 2
use &nume_tabela alias operatii
append blank
replace cod_mat with mat,;
&cantitate with val (thisform.txtcantitate.value),data_op with date( )
select 1
replace stoc with stoc + operatii.&cantitate
use in 2

Fig. 1.9 Crearea tabelelor utilizând macrosubstituţia

procedura – cmdQuit_Click
close tables
close databases
thisform.release
29

1.5 Validări la nivel de câmp şi la nivel de


înregistrare

Fig. 1.10 Tabele legate şi reguli de validare

Fig. 1.11 Definirea regulilor de validare

Dintr-o bază de date necesară unei contabilităţi informatizate fac parte şi tabelele “plan_ctb” şi
“solduri” – figura 1.10, în prima tabelă fiind memorat planul de conturi, iar în cea de-a doua tabelă soldurile
30

iniţiale la începutul exerciţiului contabil. Între cele două tabele se defineşte o relaţie de tipul 1 :1 pe baza
simbolurilor conturilor.
Pentru tabela “plan_ctb” se vor defini validări la nivel de cậmp, iar pentru tabela referită “solduri”
validări la nivel de înregistrare. Acestea din urmă sunt impuse de faptul că, un cont de activ poate avea
numai un sold iniţial debitor, iar un cont de pasiv un sold iniţial creditor.
Condiţia de validare la nivel de cậmp este dată de expresia
tip_cont = “Activ” .or. tip_cont = “Pasiv”,
iar regula impusă la nivelul înregistrărilor tabelei “solduri” este următoarea :
plan_ctb.tip_cont = “Activ” .and. sid >= 0 .and. sic = 0 .or.;
plan_ctb.tip_cont = “Pasiv” .and. sic >= 0 .and. sid = 0

În formularea celei de-a doua condiţii s-a apelat la cậmpul “tip_cont” al tabelei “plan_ctb”, acest
lucru fiind posibil datorită relaţiei existente între cele două tabele.

Fig. 1.12 Efectul regulii de validare definite la nivelul înregistrărilor tabelei “solduri”

1.6 Crearea dinamică a bazelor de date


Există situaţii în care structura unei baze de date se cunoaşte doar în momentul execuţiei unei
aplicaţiei în funcţie de anumite opţiuni specificate de către utilizator.
Considerăm următorul exemplu de evidenţă a unei situaţii scolare – figura 1.13. Numărul de
discipline din fiecare an de studiu se va specifica de către utilizator şi în funcţie de acesta se vor crea tabelele
anuale de evidenţă scolară.
Baza de date “evid” va conţine tabela primară “date_pers” şi tabele fiu “anul1”, “anul2”, “anul3”,
“anul4”. În procedura de creare a bazei de date s-au utilizat macrosubstituţia şi comanda ALTER TABLE de
ajustare a structurii tabelelor.

procedura – cmdcreare_Click
nr1 = val(thisform.text1.text)
nr2 = val(thisform.text2.text)
nr3 = val(thisform.text3.text)
nr4 = val(thisform.text4.text)
for i = 1 to 4
nr_note = "nr"+ltrim (str(i))
31

nume_tabela = "anul"+ltrim(str(i))
create table &nume_tabela (nr_leg N(10) primary key ;
references date_pers, n1 N(2) check n1>0 and n1<11)
for j = 2 to &nr_note
nume_camp = "n"+ltrim(str(j))
alter table &nume_tabela add column &nume_camp N(2);
check &nume_camp >0 and &nume_camp<11
next j
next i

Fig. 1.13 Crearea dinamică a unei baze de date

S-ar putea să vă placă și