Documente Academic
Documente Profesional
Documente Cultură
2
stocate in mai multe tabele legate intre ele prin coloane comune pot duce in lipsa unor
algoritmi specifici la timpi de executie inacceptabili. De aceea orice SGBD are
mecanisme prin care minimizeaza timpul de raspuns, mecanisme bazate in special pe
indecsi si modalitati specifice de organizare fizica a datelor.
1. Descrierea datelor
3
tabele sunt accesate de sistem pentru a regasi informatiile necesare executiei cererilor dar
pot fi accesate si de utilizatori pentru a obtine informatii privind structura bazei de date.
Astfel, toate informatiile de sistem necesare unui SGBD relational sunt stocate in
acelasi mod, inclusiv descrierea utilizatorilor si a drepturilor de acces ale acestora.
Aceasta abordare a fost necesara pentru a nu avea mecanisme diferite de acces la datele
de sistem si la datele stocate in baza de date.
2. Utilizarea datelor
3. Integritatea datelor
4
In cazul in care o operatie are ca rezultat violarea acestor restrictii aceasta este
automat rejectata si nu are efect in baza de date.
In felul acesta este asigurata o mai mare siguranta in ceea ce priveste
corectitudinea datelor.
Sa consideram o baza de date continand informatii despre
facultati,
studentii inscrisi si
notele obtinute de acestia
Introducerea accidentala de valori incorecte in baza de date. Exemplu: restrictie
privind intervalul de valori admisibil pentru note: 0-10.
Lasarea necompletata a unor informatii necesare. Exemplu: numele studentulu.
Alocarea accidentala a aceluiasi numar matricol pentru mai multi studenti
(constrangere de unicitate a valorilor).
Introducerea accidentala a unui student cu un cod incorect al facultatii la care
acesta este inscris (constragnere referentiala)
Definirea de constrangeri de integritate nu previne insa total erorile accidentale de
operare: de exemplu introducerea din greseala a unei note de 4 in loc de 5 nu va fi
semnalata, ambele valori fiind in intervalul admisibil.
4. Confidentialitatea datelor
5
Daca notam operatiile de blocare si deblocare cu LOCK si UNLOCK, programul
de rezervare de locuri poate fi rescris.
LOCK A /* se blocheaza articolul A */
READ A /* se citeste A din BD */
A = A – 1 /* se decrementeaza A*/
WRITE A /* se scrie A in BD */
UNLOCK A /* se deblocheaza A */
Blocarea articolelor rezolva o serie de probleme, dar creaza premisele aparitiei
interblocajului, situatie in care doua executii de programe asteapta deblocarea unui articol
blocat de cealalta (deadlock)
6
La fel ca si in cazul bazelor de date centralizate, gestiunea operatiilor de blocare
este realizata printr-o componenta a SGBD numita lock manager. In cazul bazelor de date
replicate, aceasta gestiune este mai complexa deoarece presupune transformarea cererilor
de blocare lansate de catre utilizator asupra unor date logice in operatii de blocare a
datelor fizice. In principiu, fiecare nod al unei baze de date distribuite are un lock
manager care gestioneaza operatiile de blocare locale, dar care, in plus, poseda si facilitati
de cooperare si comunicare cu lock manager-urile din celelalte noduri in vederea
implementarii protocolului de control al replicilor. Atunci cand o data are mai multe copii
fizice distribuite in diferite noduri, translatarea unei cereri de blocare a acesteia in operatii
de blocare a datelor fizice se poate face in mai multe moduri, fiecare dintre acestea
constituind un protocol de control al replicilor: protocolul Write-Locks-All_Read-Lock-
One, strategia de blocare majoritara, strategia din , metoda nodului central, metoda
nodului primar, metoda copiilor primare.
7
Toleranta la defecte in BDD
Toleranta la defecte a unei baze de date centralizate este asigurata prin impunerea
protocoalelor de validare a tranzactiilor si a celor de recuperare dupa un defect. Aceste
protocoale specifica modul in care sunt executate operatiile de validare si de recuperare.
In mediu distribuit, operatiile de validare si de recuperare sunt executate in mod diferit
fata de cazul bazelor de date centralizate. Operatia de validare a unei tranzactii distribuite
presupune o anumita coordonare a actiunilor din nodurile in care este executata
tranzactia. Acest lucru este realizat prin protocolul de validare in doua faze. Similar,
operatia de recuperare a unui nod dintr-o retea distribuita presupune consultarea altor
noduri pentru a afla starea actuala a tranzactiilor in executie. Pe langa acestea, in
sistemele distribuite mai apare o componenta specifica a mecanismului de asigurare a
tolerantei la defecte, si anume protocoalele de terminare. In caz de defect la unul din
nodurile in care este executata o tranzactie distribuita, este de dorit ca tranzactia sa fie
terminata, intr-un fel sau altul, in celelalte noduri ramase functionale. Acest lucru este
realizat prin protocoalele de terminare.
Desi nu este legata direct de cele prezentate pana acum, siguranta in functionare
este o caracteristica esentiala pentru un SGBD.
Contine acele elemente care exclud sau minimizeaza posibilitatea de pierdere a
datelor datorata incidentelor software sau hardware.
Salvarea datelor. Implementarea operatiilor de salvare este mult mai sofisticata.
Este dificila efectuarea unei de còpii de siguranta consistente ale bazei de date in
conditiile in care aplicatia ruleaza non-stop si operarea nu poate fi oprita pentru
efectuarea salvarii.
Restaurarea dupa incident. La distrugerea bazei de date este necesara efectuarea
operatiei de restaurare din copie.
Multe tipuri de SGBD au posibilitatea de a inregistra toate schimbarile aparute in
baza de date sub forma unor fisiere jurnal.
In acest fel operatia de restaurare dupa incident se face restaurand ultima copie de
siguranta si reefectuand toare prelucrarile consistente inregistrate in jurnal dupa
momentul in care a fost efectuata copia [2].
3. CATEGORII DE UTILIZATORI
8
a. programatorii de aplicatie (care scriu programele aplicatie in limbaje
de programare: C, Java, etc.) sau in limbaje de programare specifice:
MySQL, Oracle, etc.);
4. NIVELE DE REPREZENTARE
O aceeasi baza de date poate fi privita din diverse perspective rezultand descrieri
diferite. Termenul consacrat pentru descrierea structurii unei baze de date este acela de
schema.
In literatura de specialitate exista o clasificare pe trei nivele a acestor descrieri:
fizic, conceptual si extern.
Gestionarea schemelor bazei de date pentru fiecare nivel este una dintre atributiile
administratorului bazei de date.
a. Nivelul fizic
La acest nivel baza de date este descrisa din perspectiva stocarii sale pe
dispozitivele fizice: identificarea discurilor si a cailor unde este stocata, numele fisierelor
care formeaza baza de date, structura fizica a acestora, etc.
Descrierea bazei de date la acest nivel poarta numele de schema fizica.
9
b. Nivelul conceptual
c. Nivelul extern
Diferitele categorii de utilizatori ai unei baze de date au nevoie in activitatea lor
doar de portiuni specifice ale acesteia. Descrierea acestor portiuni poarta numele de
scheme externe.
O baza de date are deci asociata o singura schema fizica si o singura schema
conceptuala dar mai multe scheme externe.
Independenta datelor
1. Independenta logica
Independenta logica reprezinta posibilitatea de schimbare a schemei conceptuale a
bazei de date fara modificarea schemelor externe. Conditia este ca modificarea sa nu
elimine nici unul dintre elementele necesare translatiei de la schema externa la schema
conceptuala.
Independenta logica permite:
o Adaugarea de noi tabele in baza de date
10
o Adaugarea de noi coloane in tabelele existente
o Modificarea numelor tabelelor si coloanelor existente
o Adaugarea de noi constrangeri de integritate
o Modificarea in anumite limite a tipului datelor stocate in baza de date
o Restructurarea bazei de date prin mutarea unor coloane in alte tabele,
fragmentarea unei tabele sau reunirea mai multor tabele.
Exemplu
Schema conceptuala initiala
Tabela: studenti
Coloanele tabelei: ID_stud, nume, prenume, adresa, telefon, email
2. Independenta fizica
Independenta fizica reprezinta posibilitatea de schimbare a schemei fizice a bazei
de date fara modificarea schemei conceptuale si implicit a schemelor externe.
Aceasta da posibilitatea reorganizarii fizice a bazei de date fara afectarea
aplicatiilor care o folosesc.
Independenta fizica permite:
o Schimbarea dispozitivelor fizice pe care este stocata baza de date
o Schimbarea numelor fisierelor fizice in care este stocata baza de date sau a
directoarelor unde acestea sunt plasate
o Adaugarea de noi structuri de cautare rapida (indecsi) pentru cresterea
vitezei de executie
o Schimbarea in anumite conditii a structurii fizice a fisierelor bazei de date
o Schimbarea unor parametri ai sistemului de gestiune care afecteaza modul
in care datele sunt stocate la nivel fizic.
5. MODELAREA DATELOR
11
scrierea programelor de aplicatie
functionarea lor fara anomalile care pot apare in cazul unei structuri
defectuoase.
5.1. Anomalii
SOLUTIE
12
Modelul entitate-asociere este in acest moment cel mai popular model de
comunicare a structurii bazelor de date datorita intuitivitatii si simplitatii elementelor
sale.
Imbunatatiri sale ulterioare au dus la crearea de variante ale modelului, doua
dintre acestea fiind descrise in acest capitol.
ANALIZA DE SISTEM
Se realizeaza analiza segmentului din lumea reala care va fi gestionat de aplicatia
respectiva.
Rezulta o specificatie neformalizata a cerintelor constand din doua componente:
Cerinte privind continutul bazei de date: categoriile de date care vor fi stocate si
interdependentele dintre acestea.
Cerinte privind prelucrarile efectuate de aplicatie: prelucrarile efectuate asupra
datelor, arborele de meniuri al aplicatiei, machetele formatelor de introducere si
prezentare a datelor si ale rapoartelor tiparite de aceasta.
Activitati in cadrul analizei de sistem
Analiza activitatii desfasurate la momentul respectiv de beneficiarul aplicatiei sau
de o multime reprezentativa de beneficiari
13
Analiza continutului de date si a functionalitatii aplicatiilor software – daca exista
- care vor fi inlocuite de noua aplicatie (meniuri, machete ecran, machete
rapoarte)
Analiza formularelor tipizate si a altor documente utilizate de beneficiar pentru
realizarea activitatii respective.
Identificarea interdependentelor dintre datele stocate in baza de date si a
restrictiilor privind valorile lor
Identificarea prelucrarilor care se declanseaza automat atat in cazul modificarii
bazei de date cat si la momente prestabilite de timp (de exemplu sfarsit de luna, de
an, etc.)
Identificarea operatiilor care sunt necesare beneficiarului in activitatea curenta dar
care in acest moment nu sunt realizate prin intermediul aplicatiilor software
folosite precum si a operatiilor care pot fi incluse in mod natural in noua aplicatie.
Identificarea bazelor de date existente care pot fi folosite de noua aplicatie - direct
sau printr-un import initial de date - evitandu-se reintroducerea manuala a
acestora.
Identificarea modalitatilor de transfer de date intre noua aplicatie si alte aplicatii
care ruleaza deja la beneficiar si care vor fi folosite si in viitor de catre acesta.
Identificarea necesitatilor privind datele si prelucrarile care pot fi in viitor
necesare beneficiarului, deci a posibilelor dezvoltari in timp ale aplicatiei.
PROIECTAREA CONCEPTUALA
14
NORMALIZAREA
Exista o serie de reguli care descriu ce inseamna o structura corecta. Ele definesc
asa numitele forme normale.
Pe baza structurii bazei de date si a dependentelor rezultate atat din transformare
si a altor dependente identificate de proiectant in analiza de sistem se poate face o
operatie numita normalizare: se modifica structura bazei de date astfel incat toate tabelele
din aceasta sa fie in forma normala dorita.
IMPLEMENTARE CU UN SGBD
15
C. Asocieri intre entitati
A. Entitati
Entitatile modeleaza clase de obiecte concrete sau abstracte despre care se
colecteaza informatii, au existenta independenta si pot fi identificate in mod unic.
Exemple de entitati:
Studenti,
Orase,
Angajati, etc.
Ele definesc de obicei persoane, amplasamente, obiecte sau evenimente cu
importanta informationala.
Membrii unei clase care formeaza o astfel de entitate poarta numele de instante
ale acelei entitati.
De remarcat ca in literatura de specialitate se defineste intii conceptul de multime
de entitati (sau tip de entitati) pentru ca apoi sa adopte pentru usurinta exprimarii
prescurtarea de entitate pentru acest concept.
Deci entitatea este un obiect generic care reprezinta multimea tuturor instantelor
sale.
Categorii de entitati
Entitati independente (sau tari, eng. strong) sunt cele care au existenta
independenta de alte entitati,
Entitati dependente (sau slabe, eng. weak) sunt formate din instante care isi
justifica incadrarea in clasa respectiva doar atita timp cit intr-o alta entitate (tata) exista o
anumita instanta de care sunt dependente.
Exemplu:
Intr-o baza de date de personal avem entitatile:
ANGAJATI si
COPII (ultima contine copii angajatilor companiei)
Fiecare instanta a entitatii COPII depinde de o instanta a entitatii ANGAJATI
Rezulta:
ANGAJATI: entitate independenta,
COPII: entitate dependenta
Entitatile se reprezinta grafic prin dreptunghiuri in care e inscris numele entitatii.
B. Atribute
Atributele modeleaza proprietati atomice distincte ale entitatilor.
16
Exemplu: entitatea STUDENTI poate avea atributele
o Matricola,
o Nume,
o Prenume,
o Data nasterii,
o Specializare,
o Grupa,
o Adresa
In procesul de modelare vor fi luate in considerare doar acele proprietati ale
entitatilor care sunt semnificative pentru aplicatia respectiva.
Exemplu: la entitatea STUDENTI nu vom avea atribute ca:
o Talia sau
o Culoarea_parului
acestea nefiind necesare pentru baza de date a universitatii (dar pot exista intr-o baza de
date privind personalul militar).
Clasificarea atributelor
atributele de identificare (formand impreuna identificatorul entitatii)
reprezinta acea multime de atribute care permit distinctia intre instantele
aceleiasi entitati.
atributele de descriere (sau descriptori) sunt folositi pentru memorarea
caracteristicilor suplimentare ale instantelor.
Exemplu: Pentru entitatea STUDENTI
o Matricola este atribut de identificare
o celelalte atribute sunt descriptori
Atributele se reprezinta prin ovale sau cercuri in care e inscris numele atributului.
Ele sunt conectate la entitatea pe care o caracterizeaza.
17
In crearea diagramei nu vor fi luate in consideratie decit interdependentele care
sunt necesare aplicatiei respective (pot exista si alte asocieri care nu sunt semnificative
pentru aplicatia proiectata).
Cand sunt asociate 1-2 entitati asocierile se reprezinta printr-un romb.
18
Ierarhiile de incluziune si generalizare se folosesc doar in cazul in care pentru
subclasele unor clase modelate prin entitati este nevoie de stocarea unor informatii
suplimentare specifice.
Exemplu: Intr-o baza de date de studenti este nevoie de caminul si camera
ocupata, dar doar pentru caministi. Acest fapt se poate modela printr-o entitate
suplimentare CAMINIST aflata intr-o relatie de incluziune cu entitatea STUDENT. Ea va
avea ca atribute de identificare pe cele ale tatalui iar ca atribute descriptive Caminul si
Camera.
MODELUL RELATIONAL
O problema fundamentala a unui SGBD este modul in care datele sunt organizate
in vederea stocarii si exploatarii lor de catre aplicatii. Din punct de vedere istoric, in anii
’60 au existat doua modele de organizare a datelor care au fost apoi abandonate din cauza
problemelor pe care le generau:
Modelul ierarhic,
Modelul retea.
Modelul ierarhic, folosit de IBM in sistemul IMS (care inca este unul dintre
produsele furnizate de aceasta firma), in care organizarea este sub forma arborescenta:
nodurile contin date si legaturi (‘pointeri’) catre nodurile fiu.
In cadrul modelului retea inregistrarile sunt structurate sub forma unui graf
orientat, fiecare nod putand avea mai multe inregistrari ‘tata’ si mai multi fii. Au existat
mai multe sisteme de gestiune si limbaje de programare dezvoltate pe baza acestui model
(de exemplu limbajul COBOL).
Dezavantajul principal al acestor doua modele este ca accesul la o inregistrare
necesita navigarea prin arbore sau graf pentru a o localiza.
Din acest motiv apar o serie de probleme mai ales legate timpul necesar scrierii de
noi programme si a detectarii anomaliilor care pot sa apara in proiectarea bazei de date.
19
Modelul relational al datelor, folosit in acest moment de majoritatea covarsitoare
a sistemelor de gestiune aflate pe piata a fost introdus in anul 1970 prin articolul lui
Edgar Frank Codd ”A relational model for large shared databanks”.
Avantaje:
Datele sunt stocate doar ca valori; nu exista pointeri sau navigare prin date;
Face posibila dezvoltarea de limbaje de cereri de nivel inalt in care utilizatorul
specifica ce date doreste si nu cum se ajunge la rezultat, modul in care este
calculat acesta fiind in sarcina sistemului de gestiune (exemplu de astfel de
limbaj: SQL);
Furnizeaza o baza solida pentru problemele de corectitudine a datelor
(redundanta, anomalii, etc);
Permite tratarea problemelor de independenta a datelor;
Este extensibil, putand fi utilizat si pentru modelarea si manipularea de date
complexe.
Elementele modelului
1. Domeniu
2. Relatie
3. Atribut
4. Schema unei relatii
5. Cheia unei relatii
6. Valori nule
7. Corectitudinea datelor
6.1. Domeniu
20
6.2. Relatie
6.3. Atribut
21
o Nume Produs – numele produsului
o Cantitate – Cantitate
o ID Furnizor – Codul furnizorului (nu exista doi furnizori avand
acelasi cod)
o Nume furnizor – Numele furnizorului
o Adresa furnizor – Adresa furnizorului
Continutul unei relatii (vazuta ca o tabela) poate varia in timp: se pot adauga sau
sterge linii sau se pot modifica unele dintre valorile din liniile existente.
Ceea ce ramane constanta este structura relatiei: numele relatiei, numarul si tipul
atributelor sale.
In terminologia relationala structura unei relatiei este denumita si schema relatiei.
Definitie: Schema unei relatii (eng. Relation scheme) = numele relatiei urmat de
lista atributelor sale si (eventual) de domeniul din care acestea provin.
Exista mai multe modalitati prin care se poate specifica schema unei relatii. In
exemplele urmatoare prezentam cateva dintre acestea cu referire la relatia
Exemplu Produse:
o Produse(ID, Nume produs, Cantitate, ID furnizor, Nume furnizor,
Adresa furnizor)
o Produse(ID: Numar, Nume produs: Sir40, Cantitate: Numar, ID
furnizor: Numar, Nume furnizor: Sir40, Adresa furnizor: Sir100)
In cazul prezentarii unora dintre elementele de teorie a bazelor de date relationale
se folosesc si notatii de forma: R = ABCDE. Semnificatie: schema relatiei R contine 5
atribute notate cu A, B, C, D si respectiv E.
22
O relatie fiind o multime (de tupluri) nu poate contine elemente (linii) duplicat –
spre deosebire de exemplu de un tabel Excel unde putem avea dubluri.
Rezulta ca tuplurile pot fi deosebite intre ele prin valorile aflate pe una sau mai
multe coloane din relatie.
Definitie: Cheia unei relatii = multime minimala de atribute ale caror valori
identifica in mod unic un tuplu al relatiei respective.
Cheia unei relatii este o caracteristica a schemei acesteia si nu este determinata
prin inspectarea valorilor aflate la un moment dat in relatie.
In tabela Produse cele trei linii existente pot fi identificate unic de valorile de pe 3
atribute (ID, Nume Produs si Cantitate), dar numai ID este cheie:
ID identifica (prin definitie) in mod unic un produs; rezulta ca multimea de
atribute {ID} este cheie (fiind si minimala prin natura sa}.
Multimea de atribute {ID, ID Furnizor} identifica de asemenea unic fiecare tuplu
al relatiei dar nu este cheie nefiind minimala: prin inlaturarea lui ID Furnizor multimea
ramane in continuare cheie.
Multimea de atribute {Nume Produs} nu este cheie: este posibil ca in tabela
Produse sa avem mai multe linii cu Nume Produs = ‘Crema maini, ‘Sampon’ sau
‘Fixativ’.
Asa cum am mentionat cheia se determina din semnificatia atributelor relatiei si
nu din valorile la un moment dat.
Din acelasi motiv nici una dintre celelalte multimi de atribute ale relatiei Produse
nu este cheie:
o fie nu este minimala (in cazul in care il include pe ID)
o fie nu identifica unic tuplurile relatiei (pot exista valori duble)
In termeni de tabele rezulta ca nu pot exista doua linii avand aceeasi combinatie
de valori pe coloanele care formeaza cheia tabelei respective (proprietate denumita in
literatura de specialitate si unicitatea cheii).
O relatie poate avea mai multe chei. Sa ne imaginam o relatie Studenti continand
date despre studentii romani ai unei facultati:
Studenti (ID_stud, nume, prenume, adresa, telefon, email)
In acest caz avem mai multe chei:
{ID} – pentru ca ID este un numar asignat de sistem fiecarei inregistrari, fara
repetitii.
{ NrMatricol } – pentru ca nu pot exista doi studenti ai unei facultati cu acelasi
numar matricol
23
{ CNP } – pentru ca nu pot exista doi cetateni romani (deci nici doi studenti
romani) cu acelasi cod numeric personal
{ SerieCI, NumarCI } – pentru ca nu pot exista doi cetateni romani (deci nici doi
studenti romani) cu aceeasi combinatie serie/numar carte de identitate.
Observatie: Orice relatie are cel putin o cheie: deoarece intr-o relatie nu pot exista
doua elemente identice, rezulta ca multimea tuturor atributelor relatiei este cheie sau
contine cel putin o cheie.
In literatura de specialitate si in sistemele de gestiune a bazelor de date exista trei
alte concepte legate de cheie, si anume:
o Cheie primara (eng. Primary key),
o Cheie straina (eng. Foreign key),
o Supercheie (eng. Superkey).
Uneori, unele elemente ale unei relatii (celule ale tabelei) nu au nici o valoare
concreta. Se spune ca in acel loc exista o valoare nula.
Definitie: Valoare nula (eng. Null value) = o valoare diferita de oricare alta si care
modeleaza o informatie necunoscuta sau o informatie inaplicabila.
Exemplul urmator prezinta o relatie Studenti in care exista astfel de valori nule si
care au fost simbolizate (pentru a iesi in evidenta) prin <NULL>
24
unui student este inscris pe coloana IdTutor (de exemplu Popescu si Georgescu il au ca
tutor pe studentul Ionescu avand codul 1001). In cazul studentului Ionescu insa valoarea
lui IdTutor este nula pentru ca acest student nu are la randul sau un tutor, valoarea nula
fiind cea corecta in contextul respectiv.
Constrangeri
a. NOT NULL
25
b. PRIMARY KEY
c. UNIQUE
d. FOREIGN KEY
e. CHECK
a. NOT NULL
Este o constrangere la nivelul unei coloane dintr-o tabela.
Specifica faptul ca pe coloana respectiva nu pot sa apara valori nule.
Ex.: In cazul tabelei Produse o astfel de constrangere se poate asocia
pentru toate coloanele sau doar o parte din acestea.
Orice incercare de a adauga o linie care contine valori nule pe acea
coloana sau de a modifica o valoare nenula intr-una nula va fi respinsa de
sistem.
b. PRIMARY KEY
relatie poate avea mai multe chei.
In momentul creerii tabelei corespunzatoare relatiei intr-un sistem de
gestiune a bazelor de date, una dintre ele poate fi aleasa ca si cheie
primara (principala) a tabelei respective.
O tabela nu poate avea decat o singura cheie primara, formata din una sau
mai multe atribute (coloane) ale acesteia.
SGBD-ul creaza automat structuri de cautare rapida (index) pentru cheia
primara a tabelei.
O caracteristica a cheii primare a unei tabele este (in majoritatea SGBD-
urilor) cerinta ca pe coloanele componente nu pot sa apara valori nule.
Alegerea cheii care devine cheie primara va fi facuta in concordanta cu
tipul de aplicatie in care este folosita acea tabela.
Pentru exemplul
Studenti (ID_stud, nume, prenume, adresa, telefon, email, NrMatricol, CNP,
SerieCI, NumarCI)
avand cheile { ID_stud }, { NrMatricol }, { CNP }
si { SerieCI, NumarCI } alegerea cheii primare se poate face astfel:
Studenti (ID_stud, NrMatricol, Nume, CNP, SerieCI, NumarCI)
26
In cazul in care tabela este folosita intr-o aplicatie de gestiune a datelor
privind scolaritatea, se poate alege cheia primara NrMatricol, avand in
vedere ca o serie de date privind rezultatele unui student sunt legate de
matricola sa (informatie de legatura cu alte tabele).
Studenti (ID_stud, , nume, prenume, adresa, telefon, email, NrMatricol, CNP,
SerieCI, NumarCI)
In cazul in care tabela este folosita intr-o aplicatie a politiei universitare,
alegerea se va face probabil intre CNP si (SerieCI, NumarCI), legatura cu
bazele de date de la nivelurile superioare facandu-se dupa aceste
informatii.
In ambele cazuri se poate alege cheia primara ID_stud, continand numere
unice generate automat de sistem.
c. UNIQUE
Prin acest tip de constrangere se modeleaza celelalte chei ale tabelei.
Pe coloanele unei chei definita cu UNIQUE pot insa sa apara valori nule,
unicitatea fiind verificata doar pentru valorile nenule de pe coloanele cheii
respective.
In exemplul anterior, daca s-a ales cheia primara ID_stud, pentru celelalte
trei chei se pot defini trei constrangeri de acest tip.
d. FOREIGN KEY
Sunt cazuri in care o multime de coloane ale unei tabele contin valori care
exista o cheie (primara/unica) a unei alte tabele. Sa consideram o baza de
date in care exista urmatoarele doua tabele (cheile lor primare sunt cele
subliniate):
Studenti(IdS, NumeStud, CodFacultate, IdTutor, Medie)
27
Coloana CodFacultate din tabela Studenti nu este cheie in aceasta tabela
(pot exista mai multi studenti cu aceeasi valoare pe aceasta coloana, fiind
studenti ai aceleiasi facultati) dar in mod normal contine valori care pot fi
doar dintre cele existente pe cheia primara CodFacult din tabela Facultati.
O constrangere activa de acest tip (numita si constrangere referentiala) va
avea ca efect respingerea inserarilor/modificarilor in tabela Studenti care
ar face ca pe coloana CodFacultate sa apara o valoare care nu este deja in
tabela Facultati.
Rezulta implicit ca in momentul incarcarii cu date este necesar sa fie
completata intai tabela Facultati si apoi tabela Studenti, altfel operatia de
incarcare cu date va esua din cauza violarii acestei constrangeri.
In cazul multor SGBD-uri se poate specifica in constrangere si stergerea
automata a inregistrarilor ‘fiu’ in cazul stergerii inregistrarii ‘tata’: la
stergerea liniei corespunzatoare unei facultati se vor sterge automat si
liniile din tabela Studenti continand studentii acelei facultati.
Constrangerile referentiale provin de obicei din transformarea asocierilor
unare si binare unu-unu si multi-unu (descrise in capitolul precedent).
e. CHECK
28
Acest tip de constrangere specifica faptul ca valorile unei linii din tabela
trebuie sa verifice o conditie (expresie logica).
Exemplu: Fie tabela
Studenti(IdS, NumeStud, CodFacultate, IdTutor, Medie),
pe coloana Medie putem defini o constrangere de acest tip specificand ca
valoarea (daca exista o valoare nenula) trebuie sa fie din intervalul [0, 10]. Pe
coloana NumeStud putem defini o verificare a lungimii numelui (ex.:
Lungimea >= 3).
ALGEBRA RELATIONALA
Inca din primul sau articol in care introduce modelul relational, E.F. Codd
propune si un set de operatori pentru lucrul cu relatii.
O relatie este o multime de tupluri => o parte dintre acesti operatori provin direct
din teoria multimilor.
Ceilalti operatori, introdusi in aceasta algebra pentru relatii (numita in literature
de specialitate algebra relationala) sunt specifici acesteia si au la baza operatii uzuale cu
tabele – acestea fiind reprezentarea intuitiva pentru relatii.
Dupa aparitia primelor sisteme de gestiune a bazelor de date relationale s-a
constatat insa ca aceasta algebra nu inglobeaza o serie de situatii care apar in practica:
In cazul executiei unei cereri SQL pot sa apara tabele rezultat in care exista linii
duplicat. In plus, daca pe o tabela nu a fost definita o cheie primara, putem sa avem in
aceasta mai multe linii identice.
Problema liniilor duplicat intra in contradictie cu definitia unei relatii in care nu
putem avea doua tupluri identice.
Operatori ai algebrei relationale clasice: pornind de la una sau mai multe relatii
obtinem o relatie.
Operatori ai algebrei pe multiseturi – lucreaza pe asa numitele multiseturi (in
engleza bags) care sunt asemanatoare relatiilor dar in care putem avea elemente duplicat.
Operatori care lucreaza atat pe relatii cat si pe multiseturi. Ei sunt o extensie a
algebrei relationale si pe multiseturi si provin din necesitatea de a putea rescrie orice
cerere SQL in termeni al algebrei extinse.
Exista mai multi operatori in cadrul acestei algebre, unii dintre ei fiind derivati (se
pot rescrie in functie de alti operatori). Putem imparti acesti operatori in doua categorii:
o Operatori derivati din teoria multimilor.
29
o Operatori specifici algebrei relationale
DIFERENTA
Fiind date doua relatii R si S, diferenta lor, notata R - S este o relatie care contine
tuplurile care sunt in R si nu sunt in S. Si in cazul diferentei cele doua relatii care se
reunesc trebuie sa aiba scheme compatibile.
Echivalent SQL: operatorul MINUS prin care se poate face diferenta intre
rezultatele a doua cereri SQL de tip SELECT.
INTERSECTIA
30
Fiind date doua relatii R si S, intersectia lor, notata R S este o relatie care
contine tuplurile care sunt si in R si in S. De asemenea cele doua relatii care se reunesc
trebuie sa aiba scheme compatibile.
Echivalent SQL: operatorul INTERSECT prin care se poate calcula intersectia
rezultatelor a doua cereri SQL de tip SELECT.
PRODUS CARTEZIAN
Produsul cartezian: Fiind date doua relatii R si S, produsul lor cartezian, notata R
× S este o relatie ale carei tupluri sunt formate prin concatenarea fiecarei linii a relatiei R
cu fiecare linie a relatiei S.
Rezulta de aici urmatoarele:
Numarul de atribute (coloane) ale lui R × S este egal cu suma numerelor
de atribute ale lui R si S
Numarul de tupluri (linii) ale lui R × S este egal cu produsul numerelor de
tupluri ale lui R si S
Daca in R si S avem atribute (coloane) cu acelasi nume, in produsul cartezian R ×
S vom avea atribute care au acelasi nume.
Pentru a le deosebi se prefixeaza numele atributului cu cel al relatiei din care
provine (ex.: R.A si S.A, ca in exemplul urmator).
Echivalent SQL: In clauza FROM a unei cereri SELECT apar doua (sau mai
multe) tabele. In cazul standardului SQL-3, se poate folosi clauza CROSS JOIN a unei
cereri de regasire de date de tip SELECT prin care se poate efectua produsul cartezian a
doua tabele.
Exemplu: fie relatiile
31
Rezultat:
PROIECTIA
Fiind data o relatie R si o multime de atribute ale acesteia X=A1, A2, … An,
proiectia lui R pe multimea de atribute X este o relatie care se obtine din R luand doar
coloanele din X (in aceasta ordine) si eliminand eventualele tupluri duplicat.
Notatia pentru selectie este urmatoarea:
Echivalent SQL: Clauza SELECT a unei cereri de regasire de date in care este
specificata lista de expresii care da structura de coloane a rezultatului.
Exemplu: din relatia R de mai jos dorim sa calculam
32
SELECTIA
Selectia (numita uneori restrictia): Fiind data o relatie R si o expresie logica F (o
conditie), selectia lui R in raport cu F este o relatie care se obtine din R luand doar liniile
care verifica expresia logica F.
Notatia pentru selectie este urmatoarea:
Echivalent SQL: Clauza WHERE a unei cereri de regasire de date de tip SELECT
pe care se scrie conditia pe care trebuie sa o indeplineasca liniile pentru a trece mai
departe spre rezultat.
Exemplu: din relatia R de mai jos dorim sa calculam:
JOIN
Joinul general (numit si theta-join sau q-join): fiind dare doua relatii R si S, joinul
lor (notat ) se obtine din produsul cartezian al relatiilor R si S urmat de o selectie
dupa conditia F (numita si conditie de join).
33
Denumirea de theta-join este folosita din motive istorice, simbolul q fiind folosit
initial pentru a desemna o conditie.
Rezulta ca:
In cazul in care conditia de join este una de egalitate, joinul se mai numeste si
echijoin. In restul cazurilor se foloseste sintagma non-echijoin.
34
7. TEHNICA NORMALIZARII RELATIILOR
FN1 este strans legata de notiunea de atomicitate a atributelor unei relatii. Astfel,
aducerea unei relatii in FN1 presupune introducerea notiunilor de:
- atribut simplu;
- atribut compus;
- grupuri repetitive de atribute.
Atributul simplu - Atribut compus
Prin atribut simplu (atribut atomic) se intelege un atribut care nu mai poate fi
descompus in alte atribute, in caz contrar, atributul este compus (atribut neatomic).
Exemplu: Urmatoarele exemple de atribute pot fi considerate simple sau compuse
in functie de circumstante si de obiectivele bazei de date.
- Data calendaristica – este un atribut in care apar campurile: zi, luna, an;
- Adresa – este un atribut in care apar campurile: strada, nr, bloc, scara, etaj,
apartament, localitate, judet;
- Data operatiunii bancare – este un atribut in care apar campurile data, ora;
- Buletin/carte identitate – este un atribut in care apar campurile: seria, nr.
Aceste atribute pot fi atomice sau neatomice. Astfel adresa clientilor agentiei
imobiliare intereseaza la nivel global, pe cand pentru adresa ofertei sau a cererii de
imobile este vitala prelucrarea separata a fiecarui camp considerat.
Analog, atributul „nume” reprezenta un atribut simplu al acestei baze de date,
deoarece numele clientului intereseaza la nivel global [4].
35
FACTURI
Nr_factura#
data_factura
nume_client
adresa_client
banca_client
nr_cont_client
delegat
cod_produs
denumire_produs
unitate_de_masura
cantitate
pret_unitar
valoare
valoare_tva
total_valoare_factura
total_valoare_tva
In cazul in care o factura contine mai multe produse, relatia de mai sus va avea
grupurile repetitive: „cod_produs”, „denumire_produs”, „cantitate”, „pret_unitar”,
„valoare”, „valoare_tva”.
Aducerea unei relatii universale la FN1
FN1 este tratata in general cu superficialitate, deoarece principala cerinta
– atomicitatea valorilor – este usor de indeplinit (cel putin la prima vedere).
Dintre toate formele normale, doar FN1 are caracter de obligativitate. Se spune ca
o baza de date este normalizata daca toate relatiile se afla macar in FN1.
O relatie este in FN1 daca domeniile pe care sunt definite atributele relatiei sunt
constituite numai din valori atomice. Un tuplu nu trebuie sa contina atribute sau grupuri
de atribute repetitive.
Aducerea relatiilor in FN1 presupune eliminarea atributelor compuse si a celor
repetitive.
Se cunosc trei solutii pentru determinarea grupurilor repetitive:
- eliminarea grupurilor repetitive pe orizontala (in relatia R initiala, in locul
atributelor compuse se trec componentele acestora, ca atribute simple);
- eliminarea grupurilor repetitive prin adaugarea de tupluri;
- eliminarea grupurilor repetitive prin construirea de noi relatii
Primele doua metode genereaza relatii stufoase prin duplicarea fortata a unor
atribute, respectiv tupluri, creandu-se astfel redundante masive cu multiple anomalii de
actualizare.
Metoda a treia presupune eliminarea grupurilor repetitive prin construirea de noi
relatii, ceea ce genereaza o structura ce ofera cel mai mic volum de redundanta.
Etapele de aducere a unei relatii in FN1 sunt:
36
I. se construieste cate o relatie pentru fiecare grup repetitiv;
II. in schema fiecarei noi relatii obtinute la pasul 1 se introduce si cheia primara a
relatiei R nenormalizate;
III. cheia primara a fiecarei noi relatii va fi compusa din atributele chei ale relatiei
R, plus unul sau mai multe atribute proprii.
Exemplu: Deoarece o factura poate avea unul sau mai multe produse inscrise pe
aceasta, informatiile legate de produse vor fi separate intr-o alta tabela. Aplicand etapele
de aducere la FN1, se obtin doua relatii:
FACTURI LINII_FACTURI
nr_factura# nr_factura#
zi_factura cod_produs#
luna_factura denumire_produs
an_factura unitate_de_masura
nume_client cantitate
judet_client pret_unitar
localitate_client valoare
strada_client valoare_tva
nr_strada_client
banca_client
nr_cont_client
nume_delegat
prenume_delegat
serie_CI_delegat
numar_CI_delegat
toal_valoare_factura
toal_valoare_tva
37
1. se afla in forma normala FN1 si
2. fiecare atribut care nu este cheie este dependent de intreaga cheie primara.
Etapele de aducere a unei relatii de la FN1 la FN2 sunt:
I. Se identifica posibila cheie primara a relatiei aflate in FN1;
II. Se identifica toate dependentele dintre atributele relatiei, cu exceptia acelora in
care sursa este un atribut component al cheii primare;
III. Se identifica toate dependentele care au ca sursa un atribut sau subansamblu
de atribute din cheia primara;
IV. Pentru fiecare atribut (sau subansamblu) al cheii de la pasul III se creeaza o
relatie care va avea cheia primara atributul (subansamblul) respectiv, iar celelalte atribute
vor fi cele care apar ca destinatie in dependentele de la etapa III.
Exemplu: Relatia care contine date redundante (de exemplu, modificarea
denumirii unui produs atrage dupa sine modificarea in fiecare tuplu in care apare acest
produs) este relatia LINII_FACTURI. Se observa ca nu exista nici o dependenta
functionala intre atributele necomponente ale cheii. In schimb, toate atributele care nu
intra in alcatuirea cheii compuse sunt dependente de aceasta, iar DF dintre atributul
component al cheii primare sunt: cod_produs --> denumire_produs, cod_produs -->
unitate_de_masura. Ca urmare se formeaza inca doua relatii.
Chiar daca au fost eliminate o parte din redundante, mai raman si alte redundante
ce se vor elimina aplicand alte forme normale.
Observatie:
38
Daca o relatie se gaseste in prima forma normala si cheia sa primara este formata
dintr-un singur camp, atunci ea se gaseste automat in a doua forma normala.
Observatia 1: Aceasta a treia forma normala mai poate suferi o serie de rafinari
pentru a putea obtine o structura performanta de tabele ale bazei de date. De exemplu se
observa ca „nume_client” este un camp in care este inscris un text destul de lung format
39
dintr-o succesiune de litere, semne speciale (punct, virgula, cratima), spatii, numere.
Ordonarea si regasirea informatiilor dupa astfel de campuri este lenta si mai greoaie decat
dupa campuri numerice. Din acest motiv se poate introduce un nou atribut „cod_client”
care sa fie numeric si care sa fie cheia primara de identificare a pentru fiecare client.
Observatia 2: O alta observatie care poate fi facuta in legatura cu tabelele aflate in
cea de a treia forma normala este aceea ca „total_valoare_factura” este un camp care ar
trebui sa contina informatii sintetice obtinute prin insumarea valorii tuturor ofertelor
aflate pe o factura. Este de preferat ca astfel de campuri sa fie calculate in rapoarte sau
interogari si sa nu fie memorate in tabelele bazei de date.
40
8. APLICATII MICROSOFT ACCESS
Putem trece acum la crearea efectiva a bazei de date. Mai intai trebuie creat
fisierul mdb al bazei care pastreaza descrierea obiectelor bazei de date: tabele,
interogari, rapoarte, formulare. Procedura este urmatoarea:
1. Selecta consecutiv din meniul principal optiunile : File, New, Blank Database;
2. In caseta File name se tasteaza numele fisierului mdb, care va fi de fapt chiar
numele bazei de date;
3. Incheiem cu un clic pe butonul Create;
4. Avem la dispozitie acum fereastra Database care ne permite selectia obiectelor
asociate bazei de date in vederea crearii, modificarii sau activarii.
Tabelele se creeaza cel mai simplu in modul de lucru Design View. Procedura de
operare este urmatoare:
1. Selectam din fereastra Database, clasa de obiecte Tables;
41
2. Selectam cu un dublu clic modul de lucru: Create Table in Design View;
3. Fereastra Table Designer are doua panouri orizontale:
- cel de sus, pentru introducerea numelui si tipul fiecarui camp,
- cel de jos pentru setarea proprietatilor campului.
4. Se descriu succesiv campurile fiecarui tabel in parte, fara campul ID pe care-l
adauga Access la momentul inchiderii ferestrei Table Designer. Fereastra se inchide dupa
descrierea fiecarui tabel si se redeschide la tabelul urmator.
42
43
Aplicatia 2: Gestiunea facturilor unei societati comerciale
44
45
Aplicatia 3: Evidenta imprumutului cartilor dintr-o biblioteca
46
47
8.3. Definirea relatiilor intre tabele
48
pe ecran apare o fereastra care cere confirmarea legaturii. Apasam butonul Create pe
ecran apare legatura desenata ca o linie.
49
Aplicatia 3: Evidenta imprumutului cartilor dintr-o biblioteca
Incarcarea date in tabele este pasul urmator. Operatia este cunoscuta si sub
numele de “populare a bazei de date”. Procesul de incarcare se face cu ajutorul interfetei
vizuale care se activeaza astfel:
1. Efectuam dublu-click pe numele tabelului in fereastra Database;
2. Tastam valorile pentru fiecare camp, trecand la campul urmator cu un TAB;
3. La sfarsit inchidem fereastra de lucru pentru tabelul curent si repetam
procedura cu tabelul urmator.
50
8.5. Realizarea de interogari
Interogare:
51
Rezultat:
Interogare:
Rezultat:
52
9.LIMBAJUL SQL
Cea mai simpla forma a cererii SQL de creare a unei noi tabele are urmatoarea
sintaxa:
CREATE TABLE [schema.]nume_tabela
(nume_coloana_1 tip_coloana_1 [DEFAULT expresie_1],
nume_coloana_2 tip_coloana_2 [DEFAULT expresie_2],
...
nume_coloana_n tip_coloana_n [DEFAULT expresie_n]);
unde:
nume_tabela este numele tabelei care se creaza,
nume_coloana_1, nume_coloana_2, ... sunt numele coloanelor acesteia
tip_coloana_1, tip_coloana_2, ... reprezinta tipurile de date pentru
coloanele respective, alese dintre cele prezentate in paragraful anterior, cu
specificarea, daca este cazul, a dimensiunii maxime sau preciziei,
clauza optionala DEFAULT expresie_i specifica o valoare implicita care
este introdusa automat in acea coloana in cazul in care la adaugarea unei
noi linii nu se specifica o valoare pe coloana respectiva,
schema este numele de utilizator al proprietarului noii tabele. Valoarea
implicita pentru acesta este numele utilizatorului care executa cererea de
creare.
TREBUIE CA:
Utilizatorul are drepturile necesare (dreptul sau privilegiul - in terminologia
uzuala - de CREATE TABLE).
Exista spatiu de stocare pentru noua tabela.
Numele tabelei si al coloanelor respecta restrictiile uzuale Oracle (maxim 30
de caractere, incepe cu o litera, contine litere, cifre si caracterele _, $, #, nu
este cuvant rezervat). Sunt permise si alte caractere daca numele este inclus
intre ghilimele.
Nu exista deja un alt obiect cu acelasi nume in aceeasi schema (pentru acelasi
utilizator).
Ca si in cazul cuvintelor cheie, literele mici si cele mari sunt considerate egale in
numele de tabele si coloane.
Exemplu: tabela de studenti din exemple este aceeasi daca la creare se foloseste
oricare din numele STUD, Stud sau StuD.
OBSERVATII
Expresia din clauza optionala DEFAULT trebuie sa se evalueze la o valoare de tip
compatibil cu al coloanei respective. Ea poate contine:
53
Constante numerice sau sir de caractere,
Functii SQL, inclusiv SYSDATE sau USER.
dar nu poate contine:
Numele unei coloane,
Numele unei pseudocoloane. (de exemplu pseudocoloanele
definite de o secventa: NEXTVAL sau CURRVAL).
Exemplu
CREATE TABLE STUD(
MATR NUMBER(4),
NUME VARCHAR2(10),
AN NUMBER(1) DEFAULT 1,
GRUPA VARCHAR2(6),
DATAN DATE,
LOC VARCHAR2(10) DEFAULT 'BUCURESTI',
TUTOR NUMBER(4),
PUNCTAJ NUMBER(4) DEFAULT 0,
CODS NUMBER(2) );
Observam ca:
MATR, AN, TUTOR, PUNCTAJ si CODS care contin valori de tip numar
intreg au fost definite ca NUMBER(n) unde n este 1, 2 sau 4,
NUME, GRUPA si LOC sunt siruri de caractere de lungime variabila definite
ca VARCHAR2,
DATAN care contine data nasterii studentului este de tipul DATE,
Pentru unele dintre coloane au fost asociate valori implicite care vor fi stocate
automat in acestea daca la inserarea unei noi linii nu se specifica o valoare,
nula sau nenula.
Valorile implicite sunt compatibile cu tipul coloanelor respective (intreg sau
sir de caractere, dupa caz).
54
arata ca fractiunile de secunda sunt memorate cu 3 zecimale. Numele coloanei
contine un spatiu si a trebuit pus intre ghilimele.
DURATA: durata evenimentului in zile, ore, minute, secunde si fractiuni de
secunda. Numarul de zile poate avea maxim 2 cifre iar numarul de secunde
maxim 3 zecimale.
DESCRIERE (PE LARG): contine un text de descriere a evenimentului care
poate avea pana la 2 GB caractere. Se folosesc ghilimelele pentru ca numele
coloanei contine spatii si paranteze.
Clientul SQL*Plus pune la dispozitie comanda DESCRIBE prin care se pot afisa
numele coloanelor, tipul acestora si eventualele constrangeri de tip NOT NULL.
Sintaxa comenzii SQL*Plus este:
DESCRIBE nume_tabela
Observatie: DESCRIBE nu este o cerere SQL ci o comanda SQL*Plus. Ea nu
trebuie terminata cu punct si virgula (;).
Exemplu. Pentru a obtine descrierea tabelei SPEC folosim comanda:
DESCRIBE SPEC
Rezultat obtinut:
Name Null? Type
--------------- -------- -----------------
CODS NUMBER(2)
NUME VARCHAR2(10)
DOMENIU VARCHAR2(15)
Sintaxa:
ALTER TABLE nume_tabela ADD (nume_coloana tip_date [DEFAULT
expresie] [constrangere]);
Exemplu: Adaugarea unei noi coloane la tabela SPEC in care se memoreaza anul
infiintarii fiecarei specializari:
ALTER TABLE SPEC ADD(AN_INFIINTARE NUMBER(4)
CONSTRAINT ANS_NENUL NOT NULL);
Daca tabela contine deja cel putin o linie, pe noua coloana vor fi prezente
doar valori nule. Adaugarea unei coloane care are asociata o constrangere de tip NOT
NULL (ca in exemplul anterior) nu se poate face decat in cazul in care tabela nu contine
55
nici o linie. Coloana se va adauga intotdeauna dupa celelalte, devenind ultima coloana
din tabela.
Daca tabela contine deja cel putin o linie, pe noua coloana vor fi prezente doar
valori nule.
Adaugarea unei coloane care are asociata o constrangere de tip NOT NULL (ca in
exemplul anterior) nu se poate face decat in cazul in care tabela nu contine nici o linie.
Coloana se va adauga intotdeauna dupa celelalte, devenind ultima coloana din
tabela.
Sintaxa:
ALTER TABLE nume_tabela DROP COLUMN nume_coloana [CASCADE
CONSTRAINTS];
sau
ALTER TABLE nume_tabela DROP (lista coloane) [CASCADE CONSTRAINTS];
Cererea se poate executa atat in cazul in care tabela este goala cat si daca ea
contine deja linii. Daca tabela are doar o singura coloana, aceasta nu se poate sterge.
Optiunea CASCADE CONSTRAINTS sterge suplimentar toate constrangerile de
integritate in care sunt implicate coloanele sterse, inclusiv cele de tip FOREIGN KEY
care refera valorile coloanei sau coloanelor respective.
Stergerea unei coloane este o operatie costisitoare din punct de vedere al
resurselor sistemului. De aceea, in cazul in care la un moment dat acesta este foarte
incarcat stergerea se poate face in doua etape:
Etapa 1: Marcarea ca neutilizate a unei coloane sau a unei liste de coloane prin
optiunea SET UNUSED. Sintaxa este:
ALTER TABLE nume_tabela SET
UNUSED(lista_coloane);
sau
ALTER TABLE nume_tabela SET UNUSED COLUMN
nume_coloana;
Etapa 2: Stergerea efectiva a coloanelor marcate ca neutilizate la un moment
ulterior de timp, cand sistemul nu mai este foarte incarcat. Sintaxa cererii este:
ALTER TABLE nume_tabela DROP
UNUSED COLUMNS;
56
Exemple:
Pentru marcarea coloanelor DATAN, LOC si TUTOR din tabela STUD se pot
executa cererile:
ALTER TABLE STUD SET UNUSED(DATAN, LOC);
ALTER TABLE STUD SET UNUSED COLUMN TUTOR;
Stergerea coloanelor marcate se face prin cererea:
ALTER TABLE SPEC DROP UNUSED COLUMNS;
Observatii:
Coloanele marcate ca neutilizate
nu mai apar in structura afisata de DESCRIBE,
nu mai pot fi folosite in cererile SQL asupra tabelei respective
se pot adauga noi coloane in tabela avand acelasi nume.
Sintaxa:
ALTER TABLE nume_tabela
MODIFY(nume_coloana [tip_date] [DEFAULT expresie] [constrangere])
Prin aceasta cerere se pot modifica urmatoarele caracteristici ale unei coloane:
Se poate schimba tipul de date al coloanei
Se poate asocia o noua valoare implicita
Se poate adauga o constrangere de tip NOT NULL pentru acea coloana.
Printr-o singura cerere se pot efectua toate operatiile de mai sus sau doar o parte a
lor.
Exemplu:
Modificarea caracteristicilor coloanelor NUME si DOMENIU din tabela SPEC
este efectuata prin urmatoarele trei cereri de tip ALTER TABLE:
ALTER TABLE SPEC MODIFY (DOMENIU VARCHAR2(20) CONSTRAINT
DOM_MENUL NOT NULL);
ALTER TABLE SPEC MODIFY (DOMENIU DEFAULT 'NECOMPLETAT');
ALTER TABLE SPEC MODIFY(NUME CONSTRAINT NUME_NENUL NOT
NULL);
In ceea ce priveste modificarile tipului de date asociat unei coloane, acestea pot fi:
Cresterea dimensiunii coloanelor de tip sir de caractere,
Cresterea dimensiunii si preciziei datelor numerice,
Schimbarea tipurilor CHAR in VARCHAR2 si reciproc doar daca au
aceeasi dimensiune.
57
Doar in cazul in care tabela este goala sau coloana contine doar valori nule se mai
pot efectua si operatiile:
Scaderea dimensiunii coloanelor de tip sir de caractere
Scaderea dimensiunii si preciziei datelor numerice,
Orice alta schimbare a tipului coloanei respective.
In cazul schimbarii valorii implicite pentru o coloana, noua valoare va fi
folosita doar pentru inserarile de linii ulterioare modificarii.
Sintaxa:
TRUNCATE TABLE nume_tabela [REUSE STORAGE];
Exemplu: golirea tabelei SPEC se poate face prin cererea SQL TRUNCATE
TABLE SPEC;
Optiunea REUSE STORAGE este folosita pentru a specifica faptul ca spatiul
ocupat de liniile sterse ramane alocat tabelei si poate fi folosit la inserarile ulterioare in
aceasta.
In lipsa acestei optiuni spatiul respectiv devine disponibil, putand fi utilizat si
pentru alte tabele.
Sintaxa:
DROP TABLE nume_tabela;
Exemplu: stergerea tabelei SPEC se poate face prin cererea SQL DROP TABLE
SPEC;
Observatie: stergerea unei tabele este definitiva. O data stearsa ea poate fi
restaurata doar din salvarile bazei de date efectuate de administrator.
Sintaxa:
RENAME nume_vechi TO nume_nou
Exemplu: redenumirea tabelei SPEC se poate face prin cererea SQL
RENAME SPEC TO SPECIALIZARI;
Observatie: comanda RENAME nu este specifica tabelelor ci tuturor obiectelor
din baza de date.
Cu ajutorul ei se pot redenumi de asemenea vederi, secvente si sinonime.
58
9.3. CERERI SELECT
59
LISTA SELECT
Se considera urmatoarea baza de date:
60
Nu poate fi folosit decat in cererea curenta.Sistemul nu stocheaza in baza
de date sau altundeva aceste nume alternative.
Nu poate fi folosit in alte clauze ale cererii(doar in SELECT si ORDER
BY).
Exemplu:
SELECT TIP AS "Tip bursa", ' are valoarea ' || SUMA || '.Lei' AS Descriere
FROM BURSA;
Rezultat:
Tip bursa DESCRIERE
FARA BURSA are valoarea .Lei
BURSA SOCIALA are valoarea 100.Lei
- CLAUZA WHERE
Sintaxa:
WHERE expresie_logica Exemplu: SELECT NUME, GRUPA, CODS FROM
STUD WHERE AN = 4;
Operatori de comparatie:
= Egal
> Mai mare
>= Mai mare sau egal
< Mai mic
<= Mai mic sau egal
<> Diferit
!= Diferit
^= Diferit
61
AN=2 AND PUNCTAJ>500 OR CODS=11 -AN=2 AND (PUNCTAJ>500 OR
CODS=11)
- Operatorul BETWEEN:
Sintaxa:
expresie BETWEEN valoare_minima AND valoare_maxima
Exemplu:
SELECT NUME, AN, PUNCTAJ FROM STUD WHERE PUNCTAJ BETWEEN
2000 AND 4000;
Alte exemple
SELECT NUME, AN, PUNCTAJ FROM STUD WHERE PUNCTAJ + 100
BETWEEN TUTOR -2000 AND TUTOR + 1000;
SELECT NUME, LOC, DATAN FROM STUD WHERE LOC BETWEEN 'A' AND 'L'
AND DATAN BETWEEN '1-AN-2' AND '31-DEC-82';
- Operatorul IN
Sintaxa:
expresie IN (val_1, val_2, ..., val_n)
Exemple:
SELECT NUME, AN, DATAN FROM STUD WHERE TUTOR IN (1456, 2146);
o IN ignora valorile nule din lista: SELECT NUME, AN, GRUPA,
TUTOR FROM STUD WHERE TUTOR IN (NULL, 1456, 2146)
o NOT IN intoarce fals daca lista contine valori nule:
SELECT NUME, AN, GRUPA, TUTOR FROM STUD WHERE TUTOR NOT IN (NULL,
1456, 2146);
o IN este operator derivat:
SELECT NUME, AN, DATAN FROM STUD WHERE TUTOR=1456 OR TUTOR=2146;
Alte exemple:
SELECT NUME, PUNCTAJ, CODS FROM STUD WHERE PUNCTAJ + 10 IN
(CODS*30+70, CODS*200+700);
SELECT NUME, LOC, DATAN FROM STUD WHERE LOC IN ('BUCURESTI',
'PLOIESTI'OR DATAN IN ('02-SEP-5', '19-APR-84''29-AUG-84');
62
- Operatorul LIKE:
Sintaxa:
expresie LIKE 'SABLON' [ESCAPE 'caracter'] Caractere de inlocuire in sablon:
Caracter Semnificatie _ Orice caracter % Orice sir de caractere, inclusiv sirul vid
Exemple
SELECT NUME, AN, GRUPA FROM STUD WHERE NUME LIKE 'A%';
SELECT NUME, GRUPA FROM STUD WHERE NUME LIKE '____';
SELECT NUME, DOMENIU FROM SPEC WHERE DOMENIU LIKE '% %';
Alte exemple:
SELECT NUME, DOMENIU FROM SPEC WHERE NUME LIKE '%A%I_';
SELECT NUME||'_'||DOMENIU AS NUMESIDOMENIU FROM SPEC WHERE
NUME||'_'||DOMENIU LIKE '%\_U%ESCAPE '\'
- Operatorul IS NULL
Sintaxa:
expresie IS NULL --iar negata este: expresie IS NOT NULL
Valorile nule nu se pot compara cu =, <>
SELECT NUME, TUTOR FROM STUD WHERE TUTOR = NULL; --fals mereu
SELECT NUME, TUTOR FROM STUD WHERE TUTOR <> NULL; --fals mereu
Exemple:
63
SELECT NUME, TUTOR FROM STUD WHERE TUTOR IS NULL;
SELECT NUME, TUTOR FROM STUD WHERE TUTOR IS NOT NULL;
- CLAUZA ORDER BY
Sintaxa:
ORDER BY criteriu1 [DESC] [,criteriu2 [DESC]...]
Cuvantul cheie optional DESC (de la englezescul ng) specifica inversarea ordinii
de iddescen sortare implicite pentru criteriul respectiv (ordinea ascendenta, crescatoare)
astfel incat sortarea se face descendent (descrescator)
Efect:
In cazul in care ORDER BY contine mai multe criterii de sortare, ele nu sunt
echivalente ci se iau in considerare in ordinea specificata:
Se sorteaza rezultatul dupa primul criteriu
Pentru valori egale pentru primul criteriu se ia in considerare al doilea criteriu
Pentru valori egale pentru primele doua criterii se ia in considerare al treilea
criteriu, s.a.m.d.
ORDER BY – coloane din rezultat
SELECT NUME, DOMENIU, CODS FROM SPEC ORDER BY NUME;
SELECT NUME, AN, GRUPA, DATAN, CODS FROM STUD ORDER BY AN
DESC, NUME
ORDER BY – alias de coloana
SELECT NUME, PUNCTAJ, (PUNCTAJ+20)*1.1 PMARIT FROM STUD
WHERE CODS=11 ORDER BY PMARIT; -
ORDER BY expresii (coloane si aliasuri)
SELECT NUME, PUNCTAJ, (PUNCTAJ+20)*1.1PMARIT FROM STUD
WHERE CODS=11 ORDER BY (PUNCTAJ+20)*1.1;
SELECT NUME, PUNCTAJ, (PUNCTAJ+20)*1.1PMARIT FROM STUD
WHERE CODS=11 ORDER BY PUNCTAJ-MARIT;
ORDER BY – coloane care nu apar in rezultat
SELECT NUME, AN, GRUPA FROM STUD WHERE AN=2 ORDER BY LOC
DESC, (PUNCTAJ/10)
SELECT MATR, NUME, AN FROM STUD ORDER BY 3 DESC, 2;
SELECT MATR, NUME, AN FROM STUD ORDER BY 3 DESC, NUME;
Numarul de coloana nu se poate da printr-o expresie:
64
SELECT MATR, NUME, AN FROM STUD ORDER BY 2+1 DESC, NUME;
ORDER BY – Valori nule
Sunt considerate mai mari decat orice valoare (Oracle):
SELECT TIP, SUMA FROM BURSA ORDER BY SUMA
Rezultat:
TIP SUMA
BURSA SOCIALA 100
BURSA DE STUDIU 150
BURSA DE MERIT 200
BURSA DE EXCEPTIE 300
FARA BURSA
JOIN
Operatia care permite astfel de regasiri se numeste join(termen preluat din limba
engleza) si este realizata prin intermediul unei cereri SELECT avand urmatoarele
caracteristici:
o In clauza FROM este specificata nu doar singura tabela ci o lista de
tabele.
o In clauza WHERE exista o conditie care sa coreleze liniile
tabelelor din lista FROM (conditie numita si conditiedejoin)
Sintaxa
65
SELECT [DISTINCT] lista_de_expresii FROM lista_de_tabele WHERE conditie_de_join
AND conditii_suplimentare ... --alte clauze: GROUP BY, HAVING, ORDER BY
Observatii
Atunci cand conditia de join lipseste, fiecarelinie a unei tabele din lista FROM
este concatenata cu fiecare linie a celorlalte tabele, obtinandu-se de fapt
produsul cartezianal acestora.
Daca in conditia de join apar numai egalitatioperatia este numita si echijoin.
In celelalte cazuri avem un non-echijoin.
In lista de tabele care participa la join otabela poate sa apara repetat. O astfel
deoperatie este numita si joinuluneitabele cueainsasisau self-join.
In cazul in care o linie a unei tabele nu se coreleaza prin conditia de join cu
nici o linie din celelalte tabele ea nu va participa la formarea rezultatului. Se
poate insa cere ca aceasta sa fie luata in considerare pentru rezultat, rezultand
asa numitul joinextern(in engleza outerjoin).
In versiunile anterioare sintaxa joinului in Oracle eradiferita de standardul
ANSI. Incepand cu versiunea Oracle 9i au fost introduse in limbaj si tipurile
de join din standardul SQL:1999 (SQL-3) printre care cross-join,joinnaturalsi
mai multe variantedejoin extern.
PRODUS CARTEZIAN
Cererea: SELECT * FROM STUD, SPEC; va returna un rezultat avand 12
coloane si 36 de linii formate din concatenarea fiecarei linii din STUD cu
fiecare linie din SPEC.
De asemenea, cererea: SELECT DATAN, DOMENIU FROM STUD, SPEC
WHERE LOC='BUCURESTI'; are un rezultat continand 15 linii
ECHIJOIN
SELECT MATR, STUD.NUME, STUD.CODS, SPEC.NUME FROM STUD, SPEC
WHERE STUD.CODS =SPEC.CODSAND DOMENIU='STIINTE EXACTE‘
Este marcata conditia de join. Restul conditiei este suplimentar
NON-ECHIJOIN
SELECT NUME, AN, TIP, SUMA FROM STUD, BURSA WHERE PUNCTAJ
BETWEEN PMIN AND PMAX ANDCODS=11
66
Este marcata conditia de join
ALIAS DE TABELA
SELECT S.NUME, S.CODS, "SP STUD".NUME, TIP FROM STUD S, SPEC "SP
STUD", BURSA WHERE S.CODS ="SP STUD".CODS AND S.PUNCTAJ BETWEEN
PMIN AND PMAX
Aliasul trebuie sa indeplineasca anumite conditii (Oracle):
Nu poate fi mai lung de 30 de caractere.
In cazul in care nu incepe cu o litera sau cand contine alte caractere dacat
litere, cifre, _si $ trebuie pus intre ghilimele (de exemplu atunci cand contine
spatii).
In cazul unui alias intre ghilimele, dimensiunea maxima de 30 de caractere nu
include ghilimelele.
Intre ghilimele literele mici sunt considerate diferite de literele mari.
Nu poate fi folosit decat in cererea curenta. Sistemul nu stocheaza in baza de
date sau altundeva aceste nume alternative.
In cazul in care o tabela are asociat un alias prin clauza FROM acesta poate si
trebuie sa fie folosit pentru prefixare in toate celelalte clauze ale cererii.
In cazul unui alias intre ghilimele literele mici sunt considerate diferite de
literele mari. Din aceasta cauza daca prima linie a cererii anterioare este:
SELECT S.NUME, S.CODS, "Sp Stud".NUME, TIP se obtine eroare
Daca pentru o tabela a fost definit un alias numele tabelei nu mai poate fi
folosit pentru prefixare. In cazul cererii anterioare, prima linie nu mai poate fi
rescrisa astfel: SELECT S.NUME, STUD.CODS,"Sp Stud".NUME, TIP
In cazul in care conditia de join nu este completarezultatul va contine un
produs cartezian intrejoinurile existente si restul tabelelor.
Exemplu: in cererea urmatoare lipseste conditia dejoin care leaga tabela BURSA
de celelalte tabele.
SELECT S.NUME, S.CODS, "SP STUD".NUME, TIP FROM STUD S, SPEC "SP
STUD", BURSA WHERE S.CODS ="SP STUD".CODS;
In acest caz rezultatul obtinut este produsulcartezian intre BURSA si joinul lui
STUD cu SPEC siva avea 60 de linii (5 linii din BURSA * 12 linii alejoinului STUD cu
SPEC).
In cazul general al unui join pe tabele, conditia de join este compusa din N-1
subconditii conectate prin AND care relationeaza intreg ansamblul de tabele. Altfel spus,
daca se construieste un graf al conditiei in care nodurile sunt tabele si arcele subconditii
de join care leaga doua tabele atunci acest graf trebuie sa fie conex.
67
JOINUL UNEI TABELE CU EA INSASI
Este obligatorie folosirea aliasurilor:
SELECT S.NUME "NUME STUD", S.AN "AN STUD", T.NUME
"NUMETUTOR", T.AN "AN TUTOR" FROM STUD S, STUD T WHERE
S.TUTOR=T.MATR
Alt exemplu: Studenti care au acelasi tutor
SELECT S1.NUME "STUDENT 1", S2.NUME "STUDENT 2", S2.TUTOR
"TUTOR" FROM STUD S1, STUD S2 WHERE S1.TUTOR=S2.TUTOR;
INCORECT! Apar si cupluri cu acelasi student
Alta varianta:
SELECT S1.NUME "STUDENT 1", S2.NUME "STUDENT 2", S2.TUTOR
"TUTOR" FROM STUD S1, STUD S2 WHERE S1.TUTOR=S2.TUTOR AND S1.MATR
<> S2.MATR
INCORECT! Apar ambele cupluri XY si YX
Varianta corecta:
SELECT S1.NUME "STUDENT 1", S2.NUME "STUDENT 2", S2.TUTOR
"TUTOR" FROM STUD S1, STUD S2 WHERE S1.TUTOR=S2.TUTOR AND S1.MATR >
S2.MATR
68
Un exemplu in acest sens este urmatorul: cererea SELECT S1.NUME "STUDENT
1", S1.PUNCTAJ "PUNCTAJ 1", S2.NUME "STUDENT 2", S2.PUNCTAJ "PUNCTAJ 2"
FROM STUD S1, STUD S2 WHERE S1.PUNCTAJ >S2.PUNCTAJ;
Asa apar toate perechile (66) plus inca linie cu studentul avand cel mai mare
punctaj: SELECT S1.NUME "STUDENT 1", S1.PUNCTAJ "PUNCTAJ 1", S2.NUME
"STUDENT 2", S2.PUNCTAJ "PUNCTAJ 2" FROM STUD S1, STUD S2 WHERE
S1.PUNCTAJ (+) > S2.PUNCTAJ;
Observatie
Marcajul de join extern se poate folosi si atunci cand conditia de join este
compusa, cu exceptia cazului in care se foloseste sau logic (OR) sau operatorul de
incluziune IN urmat de o lista care contine mai mult de o valoare. Joinul extern se poate
folosi si in conjunctie cu operatorii specifici SQL
69
Functia SQL SUBSTR intoarce un subsir al primului argument -in cazul nostru
subsirul care incepe in pozitia 2 si are lungime egala cu 1.
Rezultat:
NUME CODS NUME CODS SABLON
GEORGE 11 MATEMATICA 11 1%
VASILE 11 MATEMATICA 11 1%
MARIA 11 MATEMATICA 11 1%
GEORGE 11 GEOGRAFIE 21 1%
VASILE 11 GEOGRAFIE 21 1%
MARIA 11 GEOGRAFIE 21 1%
ISTORIE 24 4%
Mutand marcajul obtinem cererea:
SELECT S.NUME, S.CODS, F.NUME, F.CODS, SUBSTR(F.CODS, 2,
1)||'%'SABLON FROM STUD S, SPEC F WHERE S.CODS LIKE SUBSTR(F.CODS(+),
2, 1)||'%'
Returneaza 15 linii: 6 linii pentru cei 3studenti pentru care conditia de join
obisnuiteste indeplinita plus cate o linie pentru fiecaredintre ceilalti 9 studenti care nu
verifica aceasta conditie, avand valori nule pecoloanele 3 si 4.
Exista clauzele:
1. CROSS JOIN – produs cartezian
2.JOIN … USING – coloane comune
3. NATURAL JOIN – join natural
4. JOIN … ON – join general
5. OUTER JOIN … ON – join extern. Pe o clauza avem o singura tabela (nu se mai pun
toate in FROM)
1. CROSS JOIN
Implementeaza produsul cartezian:
SELECT [DISTINCT] lista_de_expresii FROM tabela1 CROSS JOIN tabela2;
Exemplu:
SELECT S.NUME, F.NUME FROM STUD S CROSS JOIN SPEC F; --36 de linii
Pentru a face join cu CROSS JOIN adaugam conditia de join in WHERE:
70
SELECT S.NUME, DATAN, F.NUME, DOMENIU FROM STUD S CROSS JOIN
SPEC F WHERE S.CODS=F.CODS;
2. JOIN … USING
Este un echijoin dupa coloane cu acelasi nume specificate in USING (deci nu
toate): SELECT [DISTINCT]lista_de_expresii FROM tabela1 JOIN tabela2 USING
(nume_coloane)
Exemplu:
Deoarece in STUD si SPEC avem coloane cu acelasi nume (NUME si CODS)
putem face echjoinul dupa CODS astfel:
SELECT S.NUME, DATAN, F.NUME, DOMENIU FROM STUD S JOIN SPEC F
USING (CODS);
Dupa cum se observa in lista USING numele coloanelor dupa care se efectueaza
joinul nu trebuie prefixat cu numele sau aliasul vreuneia dintre tabele.
Daca se doreste afisarea acelorasi date dar doar pentru studentii nascuti in
BUCURESTI se va adauga conditia suplimentara pe WHERE:
SELECT S.NUME, DATAN, F.NUME, DOMENIU FROM STUD S JOIN SPEC
FUSING (CODS) WHERE LOC='BUCURESTI';
3. NATURAL JOIN
Este un echijoin dupa toate coloane cu acelasi nume:
SELECT [DISTINCT] lista_de_expresii FROM tabela1 NATURALJOIN tabela2
Exemplu – fara linii rezultat, nici un student nu are acelasi nume cu o
specializare:
SELECT NUME, DATAN, DOMENIU FROM STUD NATURAL JOIN SPEC; --
echijoin dupa NUME si CODS
4. JOIN .. ON
Prin aceasta clauza se implementeaza un join general. Conditia de join (si
eventual si conditiile suplimentare) se pun la ON.
Sintaxa:
SELECT [DISTINCT] lista_de_expresii FROM tabela1 JOIN tabela2 ON
(expresie_logica)
Exemplu: cererea urmatoare efectueaza joinul dintre STUD si SPEC dupa coloana
CODS si contine si o linie suplimentara care opreste doar liniile corespunzatoare
71
studentilor nascuti in PLOIESTI. Aceasta conditie suplimentara se putea pune si pe
clauza WHERE.
SELECT S.NUME, DATAN, F.NUME, DOMENIU FROM STUD S JOIN SPEC F
ON (S.CODS=F.CODS AND LOC='PLOIESTI');
Rezultatul este:
NUME DATAN NUME DOMENIU MARIA 17-JUN-83 MATEMATICA STIINTE
EXACTE ION 24-AN-85 GEOGRAFIE UMANIST
Cu JOIN ON se pot calcula si non-echijoinuri. Daca se doreste o lista cu date despre
studenti si bursele acestora, urmatoarea cerere va intoarce rezultate corecte:
SELECT NUME, PUNCTAJ, TIP, SUMA FROM STUD JOIN
BURSAON(PUNCTAJ BETWEEN PMIN AND PMAX)
5. OUTER JOIN … ON
In cazul joinului extern sintaxa este urmatoarea:
SELECT [DISTINCT] lista_de_expresii FROM tabela1 LEFT \ RIGHT |OUTER
JOIN tabela2 FULL / ON (tabela1.nume_coloana1 = tabela2.numecoloana2)
a. LEFT …
In cazul LEFT OUTER JOIN valorile nule provin din tabela2. De exemplu
cererea:
SELECT S.NUME "NUME STUD",S.AN "AN STUD"T.NUME "NUME TUTOR",
T.AN "AN TUTOR" FROM STUD S LEFT OUTER JOIN STUD T ON
(S.TUTOR=T.MATR);
returneaza 12 linii si este echivalenta cu:
SELECT S.NUME "NUME STUD", S.AN "AN STUD"T.NUME "NUMETUTOR", T.AN
"AN TUTOR" FROM STUD S, STUD T WHERE S.TUTOR=T.MATR(+) --conditia de
joinextern;
b. RIGHT …
In cazul RIGHT OUTER JOIN valorile nule provin din tabela1. Cererea:
SELECT S.NUME "NUME STUD", S.AN"ANSTUD"T.NUME "NUME TUTOR",
T.AN "AN TUTOR" FROM STUD S RIGHT OUTER JOIN STUD T
ON(S.TUTOR=T.MATR);
returneaza 13 linii si este echivalenta cu:
SELECT S.NUME "NUME STUD", S.AN "AN STUD"T.NUME "NUMETUTOR", T.AN
"AN TUTOR" FROM STUD S, STUD T WHERE S.TUTOR(+)=T.MATR;
c. FULL …
In cazul RIGHT OUTER JOIN valorile nule provin din tabela1. Cererea:
72
SELECT S.NUME "NUME STUD", S.AN "AN STUD"T.NUME "NUME TUTOR",
T.AN "AN TUTOR" FROMSTUD S RIGHT OUTER JOIN STUD T ON
(S.TUTOR=T.MATR);
returneaza 13 linii si este echivalenta cu:
SELECT S.NUME "NUME STUD", S.AN "AN STUD"T.NUME "NUMETUTOR", T.AN
"AN TUTOR" FROM STUD S, STUD T WHERE S.TUTOR(+)=T.MATR;
73
BIBLIOGRAFIE
74