Limbaje de Definire Si Manipulare a Datelor
CUPRINS
1. Introducere
1.1. Evoluția organizării datelor
1.1.1. Organizarea înregistrărilor în fișiere
1.1.2. Limitele tratării bazate pe fișiere
1.1.3. Avantajele sistemelor de gestiune a bazelor de date
1.1.4. Dezavantajele sistemelor de gestiune a bazelor de date
1.2. INDEPENDENȚA DATELOR. LIMBAJELE DE DEFINIRE ȘI MANIPULARE A DATELOR
1.2.1. Independența datelor
1.2.2. Limbajele bazelor de date
1.2.2.1. Limbajul de definire a datelor
1.2.2.1.1. Definirea schemei în SQL
1.2.2.1.2. Utilizarea interogărilor SQL în cadrul aplicațiilor
1.2.2.2. Limbajul de manipulare a datelor
1.2.2.2.1. Extragerea informațiilor din bazele de date
1.2.3. Alte caracteristici SQL
1.2.4. Query-By-Example (QBE)
1.3. SISTEME DE GESTIUNE A BAZELOR DE DATE
1.3.1. Componentele unui sistem de gestiune al bazelor de date
1.3.1.1. Componenta hardware
1.3.1.2. Componenta software
1.3.1.3. Date
1.3.1.4. Proceduri
1.3.1.5. Resursele umane
1.3.2. Componentele unui sistem de gestiune a bazelor de date
1.3.3. Funcțiile sistemelor de gestiune a bazelor de date
2. Modelarea datelor
2.1. Modele de date: rețea, ierarhice, relaționale, obiectuale, hibrid
2.1.1. Istoricul bazelor de date
2.1.2. Funcțiile modelelor
2.1.3. Modele de date bazate pe înregistrări
2.1.3.1. Modelul ierarhic
2.1.3.2. modelul rețea
2.1.3.3. modelul relational
2.1.4. Modele logice orientate pe obiecte
2.1.4.1. modelul entitate-relație;
2.1.4.2. modelul orientat pe obiecte;
2.1.4.3. modelul obiectual-relațional;
2.1.5. Modele fizice de date
2.1.6. Avantajele bazelor de date relaționale
2.1.7. Chei
2.1.7.1. Cheia candidat
2.1.7.2. Cheia primară
2.1.7.3. Cheie alternativă
2.1.7.4. Cheie externă
2.2. Modele arhitecturale: mainframe, integrate, file-server, client-server, distribuite
2.2.1. Introducere
2.2.2. Istoric
2.2.3. Modelul mainframe
2.2.4. Modelul integrat
2.2.4.1. Modelul File-server
2.2.4.2. Modelul Client-server
2.2.5. Baze de date distribuite
3.1. Bazele modelului relațional
3.1.1. Modelul conceptual
3.1.2. Modelul logic
3.1.3. Modelul fizic
3.2. normalizarea bazelor de date. Forme normale
3.2.1. Normalizarea
3.2.2. Forme normale
3.3. Regulile lui Codd
3.3.1. Regula informației
3.3.2. Regula de garantare a accesului
3.3.3. Valorile NULL
3.3.4. Catalog actualizat permanent pe baza modelului relațional
3.3.5. Regula de înțelegere a sublimbajului de manipulare a datelor
3.3.6. Regula de actualizare a vederilor
3.3.7. Inserarea, actualizarea și eliminarea
3.3.8. Independența fizică de date
3.3.9. Independența logică de date
3.3.10. Independența integrității
3.4. Limbajulș MYSQL
3.4.1. Descriere
3.4.2. Tipuri de operații asupra bazelor de date
3.4.3. Tipuri de date in MySQL
3.4.4. Comenzi elementare MySQL
3.4.5. comenzi pentru interogarea bazelor de date
3.4.6. probleme rezolvate
3.4.7. probleme propuse
CONTINUT
1. INTRODUCERE ÎN BAZE DE DATE
OBIECTIVE
Oferirea unei imagini sintetice și cuprinzătoare a bazelor de date.
Cunoașterea evoluției organizării bazelor de date, bazată pe conceptul de dată, colecții de date și fișiere.
Cunoașterea avantajelor bazelor de date.
Prezentarea interdependențelor în definirea și manipularea datelor prin intermediul limbajelor bazelor de date.
Cunoașterea limbajului de definire a datelor utilizat la definirea structurii bazei de date.
Cunoașterea limbajului de manipulare a datelor utilizat la extragerea informațiilor prin intermediul clauzelor (SELECT, FROM, WHERE, GROUP BY, HAVING), operațiilor (RENAME, STRING, ORDER, DUPLICATE, SET, MODIFY) și funcțiilor agregat.
Oferirea de informații referitoare la limbajul QBE (Query-By-Example).
Prezentarea sistemelor de gestiune a bazelor de date: definiție, obiective, componente, module și funcții.
2. MODELE ȘI ARHITECTURI DE DATE
OBIECTIVE
Prezentarea în detaliu a modelelor de date: rețea, ierarhic, relațional, obiect, hibrid.
Cunoașterea funcțiilor și componentelor modelului.
Deprinderea noțiunilor și instrumentelor necesare comparării modelelor bazate pe înregistrări (rețea, ierarhic, relațional) și a modelelor logice bazate pe obiecte (entitate-relație, orientate pe obiecte, orientate pe obiecte relaționale, binare, semantice, infologice și funcționale).
Cunoașterea avantajelor bazelor de date relaționale.
Cunoașterea rolului și importanței cheilor într-o bază de date.
Dezvoltarea unei vederi generale și implementarea cunoștințelor specifice necesare comparării modelelor arhitecturale: mainframe, integrat, file-server, client-server și distribuit.
3. MODELUL RELAȚIONAL DE DATE
OBIECTIVE
Însușirea noțiunilor de bază ale unui model de date: definiții, clasificări.
Însușirea de cunoștințe referitoare la proiectarea modelului conceptual al unei baze de date în cazul modelului relațional.
Crearea modelului logic de date pe baza modelului conceptual.
Utilizarea modelului fizic de date la descrierea reprezentării datelor în ceea ce privește formatul, înmagazinarea și calea de acces.
Proiectarea logică a unei baze de date cu ajutorul tehnicii normalizării.
Cunoașterea conceptului de descompunere și a funcțiilor sale.
Cunoașterea dependențelor funcționale, multivalorice și de cuplare.
Cunoașterea formelor normale și utilizarea lor.
Prezentarea părintelui modelului relațional; unde și în ce context Dr. E.F. Codd a creat cele 12 reguli.
Înțelegerea conținutului și importanței celor 12 reguli ale lui Codd.
4. LIMBAJUL MySQL AL BAZELOR DE DATE
OBIECTIVE
Însușirea de cunoștințe referitoare la limbajul de manipulare a datelor.
Utilizarea interogărilor simple și a interogărilor ce folosesc mai multe tabele.
Captarea de informații referitoare la sistemele ce folosesc limbajul de interogare structurat al datelor.
Definirea vederilor, cunoașterea rolurilor acestora precum și a modului lor de utilizare.
Cunoașterea de elemente referitoare la vederile simple, vederile agregat și vederile de validare.
Cunoașterea caracteristicilor vederilor.
Cunoașterea condițiilor în care se pot realiza actualizări în baza de date cu ajutorul vederilor.
Lucrari de laborator
Modelul Entitate-Relatie. Reprezentari.
Construirea unui model Entitate-Relatie.
Procesul de normalizare. 1a, a 2a si a 3a forma normala.
Procesul de normalizare. Forma normala Boyce-Codd si a 4a si a 5a forma normala.
Utilizarea MySQL. Adaugarea fisierelor si alegerea tipurilor de date.
Definirea relatiilor si setarea optiunilor de integritate referentiala. Lucrul cu interogari. Inserarea si stergerea datelor din baza de date.
Utilizarea MySQL Server. Crearea tabelelor si relatiilor.
Utilizarea MySQL Server. Inserarea si stergerea datelor din baza de date.
Utilizarea MySQL Server. Obiecte din bazele de date.
Vederi. Crearea si stergerea vederilor.
Evoluția organizării datelor
Societatea contemporană, caracterizată prin afluxul fără precedent de informație de diferite tipuri și pe diverse canale, necesită strategii și instrumente din ce in ce mai complexe pentru stocare, procesare și, mai ales, interpretare. In acest context, se pune problema transformării informației în date și organizarea acestora într-o asemenea manieră încât în orice moment să poată fi extrase, cu promptitudine și exactitate, datele favorabile realizării unui scop specific.
Datele sunt fapte culese din lumea reală. Ele sunt preluate din măsurători și observații și constituie orice mesaj primit de un receptor sub o anumită formă. O percepție a lumii reale poate fi privită ca o serie de obiecte sau fenomene distincte sau interdependente.
Datele în sine nu au nici un fel de semnificație. Mai mult decât atât, nefiind altceva decât o înșiruire de litere și cifre, ele pot primi diverse interpretări, cele mai multe dintre ele fiind, de obicei, greșite. Datele se refera la numere, fapte, diferite documente etc. Informațiile se referă la date organizate, date care au fost filtrate și ordonate după anumite criterii. Dorința oricărui utilizator este obținerea de informație și nu manipularea unor date seci. Un model de date corect alcătuit oferă posibilitatea transformării informațiilor în date și a acestora înapoi în informații fără a denatura sensul lor inițial. A obține informație înseamnă, de fapt, a introduce datele disponibile într-un anumit context conferindu-le în acest fel o anume semnificație. Ceea ce se înmagazinează într-o bază de date, așa cum am arătat, sunt datele care au o natură statică în sensul că ele rămân în aceeași stare până în momentul modificării lor de către administratorul bazei de date prin intermediul unui proces manual sau automat. Pentru ca datele să poată fi transformate în informație ele trebuie organizate astfel încât să poată fi prelucrate efectiv. Pentru a determina în cazul unei aplicații modul de organizare a datelor, trebuie determinate acele caracteristici ale datelor care permit extragerea esenței înțelesului lor.
O mulțime formală și consistentă de reguli definește un model de date.
Pentru o aplicație particulară a unui model de date, numele obiectelor bazei de date împreună cu proprietățile lor și asocierile dintre ele se numește schemă.
Un ansamblu de date organizat după anumite criterii reprezintă o colecție de date.
O colecție de obiecte care au identitate proprie și sunt caracterizate de o condiție de apartenență se numește mulțime.
Procesul de definire și structurare a datelor în colecții, gruparea lor precum și stabilirea elementelor de legătură dintre componentele colecției și între colecții reprezintă organizarea datelor.
Fișierul este o colecție de date organizate pe criterii calitative, de prelucrare și de scop. Un fișier reprezintă o colecție de date aflate în asociere ce are o denumire și care este reprezentat, de obicei, cu ajutorul unei secvențe de bytes sub forma celor două vederi:
Vederea logică: reprezintă felul în care utilizatorul vede fișierul;
Vederea fizică: reprezintă felul în care fișierul este stocat în memoria externă a calculatorului.
Aceste două vederi pot fi, evident, foarte diferite între ele.
O bază de date reprezintă o colecție integrată și structurată de date operaționale înmagazinate pe un mediu de stocare. Elsmari și Navathe definesc o bază de date sub forma unei colecții de date aflate în asociere. Scopul unei baze de date este acela de a înmagazina datele în așa fel încât să se poată obține informația dorită în orice moment. Informațiile, spre deosebire de date, au un caracter dinamic în sensul că ele se modifică în funcție de datele înmagazinate în baza de date, dar și în sensul că ele pot fi procesate și prezentate în diverse feluri.
Pentru a face diferența dintre date și informații, Hernandez propune următoarea axiomă:
Datele reprezintă ceea ce se înmagazinează; informația reprezintă ceea ce se extrage.
Cu alte cuvinte, datele trebuie extrase în așa fel din baza de date încât să capete semnificație.
Evoluția în timp a metodelor de organizare a datelor e legată de soluțiile tehnice de înmagazinare a acestora și cuprinde nivelele:
1. Nivelul I – organizarea datelor în fișiere clasice;
2. Nivelul II – organizarea mixtă în fișiere;
3. Nivelul III – organizarea datelor în bazele de date clasice;
4. Nivelul IV – organizarea datelor în bazele de date relaționale;
5. Nivelul V – organizarea datelor în baze de date distribuite.
În cadrul acestei evoluții se disting etapele:
Etapa I – este perioada caracterizată de înregistrarea datelor pe benzi magnetice. Această etapă se apropie mult de sistemul manual de organizare a datelor (îndosariere – datele sunt organizate, în principal, sub formă de fișiere secvențiale datorită suportului magnetic (benzi)). Programatorii erau nevoiți să efectueze o serie de operații de gestiune a datelor, datorită puternicei legături dintre aplicații și date.
În această etapă se remarcă următoarele caracteristici:
structura logică coincide cu cea fizică și, prin urmare, programatorul trebuie să descrie și organizarea fizică a datelor pe suport, lucru incomod, la schimbarea suportului;
prelucrare organizat după anumite criterii reprezintă o colecție de date.
O colecție de obiecte care au identitate proprie și sunt caracterizate de o condiție de apartenență se numește mulțime.
Procesul de definire și structurare a datelor în colecții, gruparea lor precum și stabilirea elementelor de legătură dintre componentele colecției și între colecții reprezintă organizarea datelor.
Fișierul este o colecție de date organizate pe criterii calitative, de prelucrare și de scop. Un fișier reprezintă o colecție de date aflate în asociere ce are o denumire și care este reprezentat, de obicei, cu ajutorul unei secvențe de bytes sub forma celor două vederi:
Vederea logică: reprezintă felul în care utilizatorul vede fișierul;
Vederea fizică: reprezintă felul în care fișierul este stocat în memoria externă a calculatorului.
Aceste două vederi pot fi, evident, foarte diferite între ele.
O bază de date reprezintă o colecție integrată și structurată de date operaționale înmagazinate pe un mediu de stocare. Elsmari și Navathe definesc o bază de date sub forma unei colecții de date aflate în asociere. Scopul unei baze de date este acela de a înmagazina datele în așa fel încât să se poată obține informația dorită în orice moment. Informațiile, spre deosebire de date, au un caracter dinamic în sensul că ele se modifică în funcție de datele înmagazinate în baza de date, dar și în sensul că ele pot fi procesate și prezentate în diverse feluri.
Pentru a face diferența dintre date și informații, Hernandez propune următoarea axiomă:
Datele reprezintă ceea ce se înmagazinează; informația reprezintă ceea ce se extrage.
Cu alte cuvinte, datele trebuie extrase în așa fel din baza de date încât să capete semnificație.
Evoluția în timp a metodelor de organizare a datelor e legată de soluțiile tehnice de înmagazinare a acestora și cuprinde nivelele:
1. Nivelul I – organizarea datelor în fișiere clasice;
2. Nivelul II – organizarea mixtă în fișiere;
3. Nivelul III – organizarea datelor în bazele de date clasice;
4. Nivelul IV – organizarea datelor în bazele de date relaționale;
5. Nivelul V – organizarea datelor în baze de date distribuite.
În cadrul acestei evoluții se disting etapele:
Etapa I – este perioada caracterizată de înregistrarea datelor pe benzi magnetice. Această etapă se apropie mult de sistemul manual de organizare a datelor (îndosariere – datele sunt organizate, în principal, sub formă de fișiere secvențiale datorită suportului magnetic (benzi)). Programatorii erau nevoiți să efectueze o serie de operații de gestiune a datelor, datorită puternicei legături dintre aplicații și date.
În această etapă se remarcă următoarele caracteristici:
structura logică coincide cu cea fizică și, prin urmare, programatorul trebuie să descrie și organizarea fizică a datelor pe suport, lucru incomod, la schimbarea suportului;
prelucrarea se face pe loturi;
dependența aplicațiilor față de date (o modificare în structura datelor sau a dispozitivului de memorare implică modificări ale programelor de aplicație și recompilarea lor și, ca urmare, trebuie ca datele să fie redefinite în cadrul aplicației ori de câte ori apare o modificare în structura bazei de date);
redundanță mare în memorarea datelor datorită faptului că aceleași date sunt memorate separat pentru fiecare aplicație ce are nevoie de ele;
legăturile dintre fișiere trebuie specificate în cadrul programelor aplicație;
fiecare aplicație are propriile date și este singura care le poate folosi;
programele realizează numai operații simple de intrare/ieșire.
Etapa a II-a – este caracterizată de înregistrarea datelor pe discul magnetic. Datele se pot organiza acum atât în fișiere secvențial-indexate cât și în fișiere cu acces direct. Anterior acestei etape datele erau înmagazinate în fișiere obișnuite, fie în format ISAM (Indexed Sequential Access Method) fie în format VSAM (Virtual Storage Access Method). Datele sunt înmagazinate și extrase acum în unități numite blocuri sau pagini. Spre deosebire de înmagazinarea în memoria RAM, timpul necesar extragerii unei pagini diferă în funcție de localizarea acesteia pe disc.
Caracteristicile corespunzătoare acestei etape sunt:
structura logică nu mai coincide cu cea fizică, ceea ce face ca programatorul să nu mai fie nevoit să descrie și organizarea fizică a datelor pe suport, acest lucru fiind făcut de către componentele specializate ale sistemului de operare;
prelucrarea se face online sau în timp real;
schimbarea unității de memorare nu implică modificarea programelor;
se menține redundanță mare deoarece, de multe ori, aceleași date sunt păstrate în mai multe fișiere;
datele sunt nestructurate;
mentenanța bazei de date are un cost foarte ridicat;
se menține dependența aplicațiilor față de date, accesul la date fiind foarte dificil; datorită acestei dependențe, aplicațiile noi sunt greu de proiectat;
se oferă o interfață de programare, numită API (Application Programming Interface);
accesul se face la nivel de înregistrare și nu de câmp în cadrul înregistrării;
nu se realizează accesul după chei multiple;
controlul concurenței este limitat;
legăturile între fișiere trebuie programate, ceea ce presupune definirea și deschiderea fiecărui fișier, accesarea datelor din primul fișier, prin intermediul căii de acces ce trebuie să apară în cadrul programului, după care se accesează cel de-al doilea fișier, ș.a.m.d.; deoarece aceste fișiere au un format fix, modificarea structurii unui astfel de fișier reprezintă un proces extrem de lent (mai întâi se transformă datele, apoi fișierul trebuie redefinit în cadrul fiecărei aplicații care îl accesează, fiind posibilă chiar schimbarea căii de acces spre acesta în cadrul fiecărei aplicații).
Etapa a III-a – este caracterizată de apariția bazelor de date. Datele se pot organiza acum sub forma unor fișiere integrate. Acestea permit realizarea mai multor fișiere logice pe baza acelorași date fizice.
Caracteristici corespunzătoare acestei etape sunt:
organizarea fizică a datelor e independentă de programele de aplicații;
se pot constitui fișiere logice în funcție de baza de date;
se remarcă un control integrat al datelor prin:
reducerea redundanței datelor fiind posibilă folosirea în comun a acelorași date fizice de către mai multe aplicații;
accesul la date la nivel de câmp;
eliminarea inconsistențelor;
asigurarea controlului concurenței;
asigurarea integrității datelor;
gestiunea datelor;
introducerea standardelor de disponibilitate a sistemelor;
îmbunătățirea securității datelor;
asigurarea accesului la date după chei multiple;
organizarea datelor e realizată de o componentă software (data management);
creșterea independenței datelor, prin asigurarea transparenței detaliilor referitoare la organizarea conceptuală, structurile de stocare și strategiile de acces ale utilizatorilor la:
nivel logic:
transparența organizării conceptuale;
transparența strategiilor logice de acces;
nivel fizic:
transparența organizării înmagazinării fizice;
transparența căilor fizice de acces.
Etapa a IV-a – se caracterizează prin asigurarea independenței logice și fizice a datelor față de programele de aplicație. Aceasta se realizează prin intermediul administratorului de baze de date cu ajutorul descrierii datelor la un nivel logic global.
Caracteristicile specifice acestei etape sunt:
datele sunt descrise la nivel logic global;
existența unor fișiere inverse ce permit răspunsul rapid la întrebări formulate de utilizatori;
mărirea gradului de protecție și securitate a datelor;
în afara independenței fizice a datelor apare și independența logică prin posibilitatea existenței unor modificări în structura logică fără a afecta aplicațiile;
creșterea controlului concurenței, prin existența mai multor vederi asupra datelor oferite utilizatorilor;
posibilitatea introducerii standardizării prin centralizarea gestiunii datelor cu ajutorul definițiilor în cadrul cataloagelor;
creșterea calității datelor prin introducerea constrângerilor suplimentare în cadrul bazei de date;
redundanța datelor este redusă la minim.
1.1.1. Organizarea înregistrărilor în fișiere
Cea mai eficientă și rapidă cale de a lucra cu datele existente într-o bază de date ar fi aceea de păstrare a tuturor acestor date în memoria internă a sistemului. Păstrarea tuturor datelor din baza de date în memoria internă a sistemului nu se poate face datorită faptului că, pe de o parte memoria internă este foarte scumpă, iar pe de altă parte aceasta este volatilă, motiv pentru care datele trebuie păstrate pe un suport magnetic extern. Prin urmare se impune stabilirea unei strategii de lucru cu datele aflate în baza de date, după cum urmează:
datele utilizate în mod curent se păstrează în memoria RAM a sistemului;
restul datelor se păstrează în memoria externă a sistemului (înmagazinare secundară);
copiile de siguranță a datelor se păstrează pe benzi magnetice (înmagazinare terțiară).
Pentru a organiza înregistrările unei baze de date în cadrul fișierelor se pot folosi mai multe modalități:
organizare în fișiere heap; în acest caz, orice înregistrare poate fi plasată oriunde se găsește loc în cadrul fișierului, nefiind impusă o anumită ordine;
organizare secvențială; în acest caz înregistrările sunt stocate într-o anumită ordine impusă de valoarea cheii de căutare a fiecărei înregistrări;
organizare în fișiere hash; în acest caz se folosește o funcție hash care se aplică atributelor fiecărei înregistrări; rezultatele obținute arată blocul din cadrul fișierului în care trebuie să se afle o anumită înregistrare, fiind strâns legate de structura de indexare folosită;
organizarea fișierelor în grupuri; înregistrările ce provin din mai multe tabele pot fi păstrate în același fișier; înregistrările asociate din tabele diferite sunt păstrate în același bloc astfel încât operațiile de intrare/ieșire pot parcurge înregistrările asociate din toate tabelele.
În continuare se vor prezenta câteva caracteristici suplimentare ale fișierelor secvențiale și ale celor organizate în grupuri.
Organizarea secvențială a fișierelor
Un fișier secvențial este foarte util la prelucrarea înregistrărilor aflate într-o ordine predefinită pe baza unei chei de căutare.
Înregistrările din cadrul unui astfel de fișier sunt asociate pe baza unor pointeri ce permit extragerea rapidă a datelor pe baza cheii de căutare. Înregistrările sunt înmagazinate fizic în ordinea stabilită pe baza cheii de căutare, ceea ce duce la minimizarea numărului de blocuri ce trebuie accesate, însă este dificil de păstrat această ordine pe măsură ce se fac introduceri sau ștergeri de înregistrări.
Ștergerile pot fi gestionate cu ajutorul lanțului de pointeri, dar inserările pun probleme dacă nu există spațiu în locul în care trebuie plasate înregistrările. În cazul în care spațiul necesar plasării unei noi înregistrări este disponibil în locul indicat, înregistrarea poate fi plasată în acel loc, altfel ea trebuie plasată în alt loc, iar pointerii trebuie reorganizați. În această situație anumite înregistrări nu se vor afla în ordinea fizică specificată. Dacă numărul de înregistrări care nu se află în ordinea fizică specificată este mic, nu vor exista probleme deosebite, dar dacă acest număr crește prea mult pointerii trebuie reorganizați, ceea ce presupune un mare consum de resurse și, prin urmare, astfel de operații trebuie efectuate numai atunci când sistemul nu este deloc sau este slab solicitat. Dacă inserările se fac rar, fișierul poate fi păstrat în ordinea fizică stabilită inițial, reorganizarea pointerilor făcându-se la apariția oricărei noi inserări, caz în care nu mai sunt necesare câmpurile de pointeri.
Organizarea fișierelor în grupuri
O situație foarte bună se întâlnește atunci când, în bazele de date de mici dimensiuni, fiecare tabel se află într-un fișier separat, iar înregistrările au o lungime fixă, ceea ce va conduce la reducerea dimensiunii programelor. Multe dintre sistemele de baze de date utilizate pe scară largă nu folosesc în mod direct sistemul de operare pentru gestiunea fișierelor. În această situație, bazei de date îi este alocat un singur fișier de mari dimensiuni, toate tabelele fiind păstrate în cadrul unui singur fișier. O astfel de structură pune la un loc înregistrări din mai multe tabele, permițând prelucrarea eficientă a joncțiunilor. Dacă înregistrările nu pot fi plasate toate într-un singur bloc, cele rămase vor apare în blocurile adiacente. Structura, cunoscută sub numele de grup, permite citirea celor mai multe dintre înregistrări cu ajutorul unui singur bloc.
Utilizarea grupurilor este foarte utilă în cazul prelucrării particulare a unui anumit tip de joncțiuni, dar poate conduce la scăderea performanțelor în cazul altor tipuri de interogări.
Înmagazinarea metadatelor în catalog
Informațiile referitoare la obiectele bazei de date sunt păstrate în alte tabele cunoscute sub numele de catalogul bazei de date, care conține:
denumirile tabelelor;
denumirile câmpurilor tabelelor;
domeniile de valori și lungimea câmpurilor;
denumirile șu definițiile vederilor;
constrângerile de integritate (informații despre cheile primară și externă).
Catalogul mai conține date despre utilizatorii sistemului (numele și condițiile de acces ale acestora), precum și (posibil) date descriptive și statistice, cum ar fi:
numărul de înregistrări din fiecare tabel;
metoda de stocare folosită în cazul fiecărui tabel (de exemplu, în grup).
De asemenea mai trebuie păstrate date referitoare indecșii folosiți în cadrul fiecărui tabel (denumirea indexului, denumirea tabelului pe care se aplică indexul respectiv, tipul indexului, câmpurile pe care se aplică indexul). Se poate spune că, de fapt, toate aceste date formează o altă bază de date în miniatură. Baza de date poate fi folosită pentru a înmagazina date despre propria structură, ceea ce va conduce la o structură mai complexă a sistemului, permițând utilizarea la maxim a puterii bazei de date prin asigurarea accesului rapid la datele sistemului.
Modalitatea optimă de reprezentare a datelor sistemului poate fi aleasă de către proiectantul sistemului, o posibilă reprezentare fiind următoarea:
Schema catalogului sistemului = (nume tabel, număr de atribute).
Schema atributelor = (nume atribut, nume tabel, tip de dată, poziție, dimensiune).
Schema utilizatorului = (nume utilizator, cont de utilizator, cheia de criptare, grup).
Schema de indexare = (numele indexului, numele tabelului, tipul indexului, atributul indexului).
Schema vederii = (numele vederii, definirea vederii).
1.1.2. Limitele tratării bazate pe fișiere
În general acestea sunt marcate de:
1. Separarea și izolarea datelor.
2. Dublarea datelor.
3. Dependența datelor.
4. Incompatibilitatea fișierelor.
5. Interogări statice.
Separarea și izolarea datelor
Cu sistemele de fișiere e dificilă o prelucrare a datelor atunci când acestea sunt izolate în fișiere separate. În acest caz programatorul trebuie să sincronizeze prelucrarea a două sau mai multe fișiere pentru a se asigura că datele extrase sunt cele corecte. Dificultatea este cu atât mai mare cu cât datele necesare se află în mai multe fișiere.
Dublarea datelor
Se manifestă prin faptul că aceleași date se pot afla în două sau mai multe fișiere în funcție de numărul aplicațiilor sau al utilizatorilor. În această situație pot apare o serie de probleme, cum ar fi:
creșterea costurilor prin creșterea spațiului de memorare a datelor;
apariția inconsistenței datelor prin faptul că o anumită dată poate fi memorată în mai multe locuri; atunci când există mai multe copii ale aceleiași date e posibil ca prin actualizarea unora dintre ele să existe valori diferite ale acelorași date (inconsistență); inconsistența mai poate apare și la introducerea greșită a unor date;
imposibilitatea introducerii unor standarde;
imposibilitatea aplicării restricțiilor de securitate;
imposibilitatea menținerii integrității datelor (consistență și validare).
Dependența datelor
Structura fizică și stocarea fișierelor de date și înregistrărilor sunt definite în codul aplicației. Aceasta înseamnă că orice modificare efectuată în structura existentă impune scrierea unui program de tip exe-off (adică un program ce este rulat o singură dată, după care poate fi înlăturat). Acest program trebuie:
să deschidă fișierul inițial pentru a fi citit;
să creeze un fișier temporar cu noua structură;
să citească o înregistrare din fișierul inițial, să transforme datele pentru a le încadra în noua structură și să scrie fișierul temporar. Acest lucru trebuie repetat pentru toate înregistrările din fișierul inițial;
să șteargă fișierul inițial;
să redenumească fișierul temporar cu numele fișierului inițial;
să modifice toate programele ce apelează fișierul inițial pentru a se conforma noii structuri.
Toate aceste operații necesită mult timp și sunt supuse pericolului de apariție a erorilor. Dacă structura unui fișier trebuie modificată, trebuie modificat și programul care îl folosește, deoarece programul “știe” prea multe lucruri despre structura acestuia. Diferența dintre conceptul de fișier și cel de bază de date este reprezentată în figurile următoare:
Figura 1.1. Fișiere: dependența aplicație/date
Figura 1.2. Baze de date: independența aplicație/date
Formate de fișiere incompatibile
Este posibil ca fiecare fișier să fie apelat de către un program scris într-un limbaj de programare diferit. În acest caz se impune să se scrie un program de transformare a fișierelor într-un format comun astfel încât să se poată face prelucrarea datelor din mai multe fișiere, deoarece fiecare limbaj de programare necesită un anumit tip de fișier.
Interogarea statică a programelor aplicație
În cazul în care apar noi cereri de interogare a datelor aflate în fișiere, trebuie rescrise programele existente, deoarece, altfel, nu se poate răspunde decât la întrebările existente. În cazul rescrierii programelor pot apare următoarele deficiențe:
documentație limitată și dificil de întreținut;
afectarea securității și integrității datelor;
refacerea datelor după defectarea sistemului e limitată sau inexistentă;
accesul la fișiere e restrâns la câte un utilizator odată.
În concluzie, limitările tratării bazate pe fișiere se datorează factorilor:
definiția datelor e încorporată în programele aplicație, în loc să fie stocată separat și independent;
nu există control al accesului și manipulării datelor, în afara celui impus de către programele aplicație.
1.1.3. Avantajele sistemelor de gestiune a bazelor de date
Avantajele sistemelor de gestiune a bazelor de date față de sistemele clasice, cu fișiere sunt următoarele:
Controlul redundanței datelor
Risipa de spațiu care se face prin stocarea acelorași informații în mai multe fișiere este mult diminuată prin utilizarea bazelor de date, dar nu complet eliminată datorită altor cereri de îmbunătățire a performanțelor.
Coerența datelor
Dacă un articol de date e înmagazinat de mai multe ori trebuie să se garanteze că toate copiile acestuia vor fi actualizate dacă se reactualizează o valoare a sa (valoarea articolului e aceeași pentru toate copiile sale).
Mai multe informații de la aceeași cantitate de date
Se pot obține prin integrarea fișierelor ce conțin informații diferite despre aceleași date.
Partajarea datelor
Datele pot fi utilizate de către mai mulți utilizatori în același timp. De asemenea se pot face modificări sau adăugiri la baza de date existentă fără a fi necesară definirea repetată a tuturor cerințelor referitoare la acestea.
Integritatea crescută a datelor
Se referă la validitatea și coerența datelor înmagazinate și se exprimă prin constrângeri (reguli de coerență). Constrângerile se pot aplica articolelor de date din cadrul unei singure înregistrări sau relațiilor dintre înregistrări.
Securitatea crescută
Se realizează prin atribuirea unor nume de utilizatori și parole ce permit identificarea persoanelor autorizate să folosească baza de date și impun modalitatea de utilizare a acestor date.
Aplicarea standardelor
Se referă la formatul datelor, convențiile privind denumirile, documentarea, procedurile de reactualizare, regulile de acces.
Reducerea costurilor
Prin realizarea integrării se alocă fonduri centralizat și nu separat fiecărui departament.
Rezolvarea conflictelor
Fiecare utilizator va avea propriile cerințe ce pot intra în conflict cu ale altora. Administratorul bazei de date poate lua decizii ce duc la utilizarea optimă a resurselor.
Creșterea accesibilității datelor și a capacității de răspuns
Se realizează prin intermediul utilizării limbajelor de programare din generația a IV-a (ex. SQL, QBE).
Creșterea productivității
Prin furnizarea unor funcții ce permit manipularea fișierelor și a introducerii limbajelor de programare din generația a IV-a ce reduc mult timpul de programare.
Independența datelor
Duce la creșterea capacității de întreținere prin faptul că descrierile datelor sunt separate de aplicații.
Controlul concurenței este îmbunătățit
Se garantează că dacă doi sau mai mulți utilizatori accesează simultan aceleași date nu se pierd informații sau nu se alterează integritatea acestora.
Asigurarea salvării de siguranță și a refacerii
Prin recuperarea ultimei stări coerente a bazei de date în cazul apariției unei defecțiuni hard sau soft.
1.1.4. Dezavantajele sistemelor de gestiune a bazelor de date
Complexitatea
Trebuie avute în vedere o serie de probleme referitoare la date care se manifestă suplimentar față de cazul aplicațiilor clasice. Se face mai întâi o analiză amănunțită a datelor și apoi a aplicației propriu-zise.
Dimensiunea
SGBD-urile ocupă mult spațiu pe disc.
Costul
a) sistemelor SGBD;
b) elementelor hard achiziționate;
c) conversiei aplicațiilor existente la noul SGBD și noua configurație hard.
Performanța
Este mai redusă în cazul utilizării SGBD-urilor care au un caracter mai general, în locul unei aplicații simple bazată pe fișiere care apelează o singură funcție.
Efectul unei defecțiuni
Este mult mai mare datorită centralizării (o defecțiune minoră afectează toți utilizatorii).
1.2. INDEPENDENȚA DATELOR. LIMBAJELE DE DEFINIRE ȘI MANIPULARE A DATELOR
Pornind de la lucrările lui Codd referitoare la modelul relațional și la limbajele bazate pe algebra relațională sau calculul relațional, comunitatea internațională a făcut, în timp, mari eforturi de redefinire și îmbunătățire a acestor concepte. În acest sens au fost dezvoltate o serie de versiuni ale limbajelor relaționale, cum ar fi SQL (Structured Query Language), QBE (Query-By-Example) și QUEL (Query Language).
SQL își are originile în anul 1974 când IBM l-a folosit pentru prima dată în proiectul său de cercetare System R care funcționa pe sisteme mainframe VS/2 sub denumirea de Structured English Query Language (sau SEQueL). Ulterior numele i-a fost schimbat în SQL (Structured Query Language, pronunțat “sequel” sau S-Q-L). Produsele ulterioare ale firmei IBM, SQL/DS și, apoi, popularul DB2 folosesc acest limbaj. SQL se bazează pe calculul relațional ce are în vedere utilizarea de variabile constituite din tupluri. În 1986, Institutul Național American pentru Standarde (ANSI) a elaborat și lansat standardele SQL contribuind astfel la extinderea acestuia în întreaga comunitate a producătorilor de baze de date care, deși are numeroase variante, folosește totuși același set de comenzi și structuri de bază standardizate.
Instanțe și scheme
Bazele de date se modifică des în decursul timpului. Datele aflate într-o bază de date la un anumit moment dat alcătuiesc o instanță a acelei baze de date. Proiectul general al bazei de date este denumit schema bazei de date. O schemă reprezintă o descriere a datelor conform modelului de date propus. Schema bazei de date reprezintă ceea ce în limbajele de programare clasice este cunoscut sub numele de definirea tipurilor de date, iar instanța unei baze de date este ceea ce în limbajele de programare clasice este cunoscut sub denumirea de valoarea unei variabile.
Schema bazei de date reprezintă descrierea generală a bazei de date și conține:
informațiile fizice de proiectare;
informații referitoare la utilizator;
descrieri de nivel înalt ale tranzacțiilor și aplicațiilor precum și legăturile utilizatorilor cu ele;
relațiile dintre date și tranzacții;
statistici de utilizare.
În funcție de nivelul de abstractizare corespunzător există următoarele tipuri de scheme:
Schema externă (subschema) – se află la nivel superior și corespunde unei valori a datelor. Ea descrie vederile bazei de date ce se folosesc într-o anumită aplicație și corespunde schemei conceptuale. Schema reprezintă vederea utilizatorilor asupra datelor (aplicația).
Schema conceptuală (logică) – corespunde nivelului conceptual și descrie articolele, relațiile și constrângerile dintre ele. Ea este o descriere abstractă și integrată a tuturor datelor, independent de sistemul de gestiune al bazelor de date folosit și trebuie să corespundă schemei interne. Schema reprezintă perspectiva sistemului de gestiune al bazelor de date.
Schema internă – se află la nivel inferior și conține definițiile tuturor înregistrărilor stocate în baza de date, metodele de reprezentare, câmpurile și indexurile datelor (descrie modul de stocare fizică a datelor precum și structurile de acces la date). Schema reprezintă perspectiva realizării sistemului/implementării.
Sistemul de gestiune al bazelor de date efectuează corespondențe între cele trei tipuri de scheme pentru a le corela. Dacă se produce o modificare la nivel fizic, schema internă trebuie modificată, dar schema conceptuală poate rămâne neatinsă. Corespondențele efectuate între vederile utilizatorilor (nivelul extern) și stocarea fizică a datelor (nivelul intern) ajută la ascunderea complexității nivelului fizic, ceea ce face să crească flexibilitatea și posibilitățile de adaptare. Sistemul SGBD trebuie să verifice dacă fiecare schemă externă poate fi derivată din schema conceptuală. Pentru a stabili corespondența dintre fiecare schemă externă și cea internă, sistemul trebuie să folosească informațiile din schema conceptuală.
Schema relațională
Structura relațională a unei baze de date mai este cunoscută și sub denumirea de schemă relațională (sau metastructură datorită faptului că ea descrie structura datelor). O schemă relațională reprezintă o descriere a unei colecții particulare de date, folosind un anumit model dat. Aceasta predefinește posibilele stări ale bazei de date, în sensul că nici o stare a unei baze de date nu poate conține date care să nu fie obținute în urma instanțierii schemei respectivei baze de date și nici o stare a unei baze de date nu poate conține o asociere între două seturi de date dacă această asociere nu a fost definită în schema bazei de date. În plus, procedurile de manipulare a datelor trebuie să fie separate de date. Modelul relațional al datelor este cel mai utilizat model pe plan mondial la ora actuală. Conceptul de bază ce fundamentează acest model este relația, transformată într-un tabel ce conține rânduri și coloane. Fiecare relație are o schemă ce descrie coloanele sau câmpurile tabelului. În practică, schema bazei de date conține:
definiția tipurilor de date;
definiția relațiilor, specificând pentru fiecare dintre ele:
intensia (numele tuturor atributelor);
cheia primară.
De obicei, într-un sistem relațional atât schema conceptuală cât și schema externă sunt relaționale. Pentru a prezenta proiectul unei baze de date independent de orice limbaj de definire a datelor, de obicei, se folosește o notație general acceptată care are formatul:
<nume relatie>: <lista numelor atributelor>
O astfel de notație este utilă în scopul clarificării organizării generale a bazei de date, dar nu lămurește o serie de detalii referitoare, în special, la proprietățile domeniilor de valori ale atributelor. O definire mai completă care utilizează limbajul de definire a datelor se poate face cu ajutorul notației originale propusă de Codd, în care componentele sunt descrise în amănunt. Cu ajutorul acestei notații se pot crea entitățile, atributele, domeniile de valori precum și cheile sub forma unor entități ale schemei bazei de date. Un astfel de limbaj definește doar structura acestor entități, nu și conținutul lor.
1.2.1. Independența de date
Reprezintă faptul că nivelele superioare nu sunt afectate de modificările făcute la nivelele inferioare. Aceasta înseamnă și faptul că vederea unui utilizator (schema externă) este complet independentă de vederea altui utilizator, ceea ce are un efect extrem de favorabil în cazul modificărilor efectuate de către administratorul bazei de date (ce pot apare ca urmare a cererilor venite din partea utilizatorului respectiv, ca urmare a necesităților de adaptare a sistemului la noile condiții sau ca urmare a dorinței de optimizare a funcționării sistemului) care poate face modificări ale vederii unui singur utilizator fără a afecta vederile celorlalți utilizatori. Conform arhitecturii propuse de organizațiile ANSI/SPARC se oferă două nivele de independență a datelor:
Independența logică de date
Independența fizică de date.
Independența logică de date
Se referă la imunitatea schemelor externe față de modificările efectuate în schema conceptuală. Modificările din schema conceptuală pot fi:
adăugarea sau eliminarea de noi entități;
adăugarea sau eliminarea de atribute;
adăugarea sau eliminarea de relații.
Independența logică de date înseamnă că se pot face modificări în schema conceptuală fără a fi necesară schimbarea schemei externe existente sau rescrierea programelor de aplicație. Modificările nu trebuie să afecteze toți utilizatorii ci doar pe aceia pentru care s-au făcut. Aceștia trebuie informați de acest lucru.
Independența fizică de date
Se referă la imunitatea schemei conceptuale față de modificările efectuate în schema internă. Modificările din schema internă pot fi:
organizare diferită a fișierelor;
structuri de stocare diferite;
dispozitive de stocare diferite;
indexuri sau algoritmi diferiți.
Modificările făcute în schema internă se fac cu scopul îmbunătățirii performanțelor bazei de date.
Independența de date este un concept care rămâne de multe ori un deziderat greu de realizat, chiar și în cazul sistemelor din ce în ce mai performante ale zilelor noastre. Totuși, bazele de date relaționale, datorită limbajelor relaționale pe care le folosesc, oferă un înalt grad de independență față de date. Deși, așa cum am arătat, într-un sistem relațional atât schema conceptuală cât și cea externă sunt, ambele, relaționale, totuși, schema conceptuală se construiește cu ajutorul unor instrumente ce au un caracter mult mai general decât cel oferit de modelul relațional.
Presupunând, de exemplu, că o vedere nu mai este necesară unui utilizator, datorită faptului că anumite atribute nu mai sunt de actualitate, alte atribute din baza de date prezentând interes pentru acesta, se poate efectua o modificare în clauza SELECT pentru a răspunde cererii de modificare.
Atât timp cât fiecare vedere este definită separat în funcție de schema conceptuală și atât timp cât schema conceptuală nu se modifică, orice vedere creată pe baza acelei scheme poate fi actualizată fără a afecta celelalte vederi.
Independența de date se mai folosește și atunci când se dorește să se obțină o independență a vederilor utilizatorilor față de schema conceptuală. De obicei, dacă relațiile și atributele la care se face referire în definiția vederii nu sunt eliminate cu ocazia unei modificări, vederea nu va fi afectată de modificare. În acest fel, cererile suplimentare de modificare pot fi efectuate fără teama că ele ar putea afecta aplicațiile existente care folosesc acea bază de date.
În sfârșit, independența de date se mai referă și la faptul că este posibilă modificarea schemei prin care se realizează înmagazinarea fizică a datelor, fără a afecta schemele conceptuală, respectiv externă.
1.2.2. Limbajele bazelor de date
Pentru a construi o bază de date un utilizator trebuie să:
definească schema bazei de date;
aplice o colecție de operatori pentru a crea, înmagazina, extrage și modifica datele.
Un sistem de gestiune al bazelor de date obișnuit trebuie să ofere o serie de instrumente care să ușureze activitățile specificate anterior. În acest sens, SQL trebuie să fie limbajul standard relațional al bazei de date, având următoarele componente:
un limbaj de definire a datelor (Data Definition Language – DDL), utilizat la definirea schemei bazei de date
un limbaj de manipulare a datelor (Data Manipulation Language – DML), care permite utilizatorului manipularea obiectelor bazei de date și a relațiilor dintre acestea, în contextul schemei bazei de date.
Aceste limbaje pot diferi de la un producător la altul în cadrul modelului pe care aceștia îl folosesc datorită aspectelor legate de complexitate, funcționalitate și ușurința în exploatare (interfața utilizator). De multe ori aceste limbaje sunt denumite sublimbaje de date deoarece nu includ construcții pentru toate necesitățile de calcul cum sunt cele asigurate de limbajele de nivel înalt. Majoritatea sistemelor de gestiune a bazelor de date au încorporat sublimbajul într-un limbaj de programare de nivel înalt (ex. C++). În acest caz limbajul de nivel înalt este numit limbaj gazdă.
1.2.2.1. Limbajul de definire a datelor
Permite administratorului bazei de date sau utilizatorului să descrie și să denumească entitățile din baza de date precum și relațiile ce pot exista între diferitele entități. Limbajul de definire al datelor reprezintă o colecție de instrucțiuni utilizate pentru descrierea tipurilor de date. Administratorul bazei de date trebuie să definească structura bazei de date cu ajutorul acestor tipuri de date. Acesta este utilizat pentru a defini o schemă a bazei de date sau pentru a modifica una existentă. Rezultatul compilării instrucțiunilor din limbajul de definire a datelor reprezintă un set de tabele stocate în fișiere speciale denumite cataloage de sistem. Catalogul de sistem conține meta-datele (datele care descriu obiectele din baza de date). Metadatele conțin definiții ale înregistrărilor datelor și altor obiecte cerute de sistemul de gestiune al bazei de date. Sistemul de gestiune al bazei de date consultă mai întâi catalogul de sistem pentru a accesa corect datele. Teoretic, sunt trei limbaje de definire a datelor:
pentru schema externă;
pentru schema conceptuală;
pentru schema internă.
Limbajul de definire a datelor conține comenzi necesare următoarelor operații:
definirea schemelor de relație;
eliminarea relațiilor;
crearea indecșilor;
modificarea schemelor.
Limbajul de definire a datelor permite specificarea următoarelor informații necesare în orice bază de date:
schema fiecărei relații din baza de date;
domeniul de valori asociat fiecărui atribut;
constrângerile de integritate;
setul de indecși care se creează pentru fiecare relație în parte;
informații referitoare la securitatea sistemului și la modul de acces la acesta;
structura de înmagazinare fizică pe disc a datelor.
1.2.2.1.1. Definirea schemei în SQL
O relație în SQL se definește cu ajutorul sintaxei:
CREATE TABLE r (A1;D1;A2;D2; : : :;An;Dn, constrangere_de_integritate1 i, : : : , constrangere_de_integritate1 i)
în care r reprezintă numele relației, AI reprezintă numele unui atribut, iar DI reprezintă domeniul în care ia valori acel atribut. Constrângerile de integritate permise sunt cheia primară (Aj1; : : :;Ajm) și regulile de validare a domeniului de valori (check(P)).
O cheie primară trebuie să îndeplinească două condiții:
valorile cheii primare trebuie să fie unice;
într-o cheie primară nu trebuie să apară valori nule.
Standardul SQL-92 consideră că apariția constrângerii “not null” în cheia primară este un fapt redundant, dar standardul SQL-89 cere definirea explicită a acestui lucru. Regulile de validare a domeniului de valori (check) se dovedesc a fi extrem de utile la creșterea funcționalității bazei de date dar, uneori, sunt foarte costisitoare, așa cum se întâmplă, de exemplu, în cazul folosirii cheii externe.
În cazul în care se dorește eliminarea unei relații din baza de date trebuie folosită următoarea relație:
DROP TABLE r
ceea ce nu este același lucru cu:
DELETE r
care păstrează relația, dar elimină toate tuplurile din ea.
Comanda de modificare a structurii unui tabel poate fi folosită pentru a adăuga sau elimina atribute din cadrul unei relații r existente în baza de date:
ALTER TABLE r ADD A D
în care A reprezintă atributul, iar D reprezintă domeniul de valori ce trebuie atribuit acestuia.
ALTER TABLE r DROP A
În care A reprezintă atributul care trebuie eliminat din baza de date.
1.2.2.1.2. Utilizarea interogărilor SQL în cadrul aplicațiilor
SQL este un limbaj de interogare extrem de performant, datorită avantajului oferit de prelucrarea pe seturi de înregistrări. Totuși, el nu poate oferi procedurile necesare efectuării unei serii de activități și acțiuni, cum ar fi: crearea de interfețe grafice prietenoase, crearea și imprimarea de rapoarte, interacțiuni cu alți utilizatori, transferul datelor între baza de date și aplicații. Din acest motiv este necesară utilizarea unui limbaj de programare din generația a treia care să realizeze conexiunea cu baza de date și să efectueze sarcini dintre cele arătate anterior.
Standardul SQL definește instrucțiunea EXEC care să poată fi folosită în astfel de situații:
EXEC instructiune SQL
Instrucțiunile SQL admise sunt: DECLARE CURSOR, OPEN și FETCH care prelucrează datele din baza de date înregistrare cu înregistrare, precum și instrucțiunile de modificare, inserare sau ștergere a datelor.
Componenta dinamică SQL permite crearea și utilizarea de interogări SQL care să se modifice în timpul rulării aplicațiilor. De asemenea, în standardul SQL-92 sunt introduse module ce permit definirea procedurilor în SQL.
1.2.2.2. Limbajul de manipulare a datelor
Asigură un set de procedee ce permit operații de bază pentru manipularea datelor din baza de date. Limbajul de manipulare a datelor asigură o colecție de operatori ce pot fi aplicați pentru a valida instanțele tipurilor de date în cadrul schemei și de a crea, modifica sau extrage astfel de instanțe. Cu ajutorul acestor operatori se pot efectua următoarele operații:
Regăsirea datelor din baza de date (operație principală).
Inserarea de date noi în baza de date.
Modificarea datelor existente.
Ștergerea de date din baza de date.
Există două tipuri de limbaje de manipulare a datelor:
Limabje de manipulare a datelor procedurale (specific modelelor rețea și ierarhic) care permit utilizatorului să comunice sistemului ce date sunt necesare și cum pot fi ele exact regăsite. Aceste limbaje prelucrează informația înregistrare cu înregistrare.
Limbaje de manipulare a datelor neprocedurale (specifice modelului relațional) care permit utilizatorului să comunice sistemului ce date sunt necesare fără a specifica cum se regăsesc datele. Aceste limbaje prelucrează informația pe seturi de înregistrări și au următoarele caracteristici:
conferă o mai mare independență de date;
cresc viteza de prelucrare a informației;
sunt limbaje de generația a patra (4GL – Fourth Generation Language).
Exemple de astfel de limbaje ce aparțin generației a patra sunt:
limbajul SQL;
limbajul QBE;
generatoare de formulare;
generatoare de rapoarte;
generatoare grafice;
generatoare de aplicații.
1.2.2.2.1. Extragerea informațiilor din bazele de date
Limbajul de manipulare a datelor permite extragerea datelor dintr-o bază de date. Structura de bază a unei expresii SQL constă din utilizarea clauzelor SELECT, FROM și WHERE.
SELECT este o clauză ce folosește o listă a atributelor ce urmează a fi prezentate utilizatorului și care corespunde operației de proiecție din algebra relațională.
FROM este o clauză ce corespunde produsului cartezian din algebra relațională și în care se introduc relațiile din care urmează a fi extrase atributele ce apar în clauza SELECT.
WHERE este o clauză ce corespunde predicatului de selecție din algebra relațională.
În mod obișnuit o interogare se prezintă sub forma:
SELECT A1;A2; : : :;An
FROM r1; r2; : : :; rm
WHERE P
în care fiecare AI reprezintă un atribut, fiecare ri reprezintă o relație, iar P este un predicat, ceea ce este echivalent expresiei:
A1;A2;:::;An (_P (r1 _ r2 _ : : :_rm))
Dacă se omite clauza WHERE, predicatul P are valoarea True. Lista atributelor poate fi înlocuită printr-un caracter * pentru a le alege pe toate. Prin intermediul SQL se alcătuiește produsul cartezian pe baza relațiilor precizate, se poate efectua o selecție cu ajutorul unui predicat, după care se poate face o proiecție pe anumite atribute. Rezultatul unei interogări SQL este tot o relație și, în mod implicit, înregistrările duplicat nu sunt eliminate. În lista de selecție se pot afla și operații aritmetice.
Clauza WHERE
Predicatele pot avea orice grad de complexitate și pot implica:
conexiuni logice de tip “and”, “or”, sau “not”;
expresii aritmetice ce conțin constante sau valori ale tuplurilor;
operatorul “between” utilizat pentru definirea domeniilor de valori ale variabilelor.
Clauza FROM
Clauza FROM în sine, definește un produs cartezian calculat pe baza relațiilor care sunt specificate în cadrul acesteia. SQL nu oferă echivalentul joncțiunii naturale, dar aceasta poate fi exprimată cu ajutorul unui produs cartezian urmate de operațiile de selecție și proiecție. Variabilele, care în SQL sunt reprezentate de tuplurile relațiilor, se definesc în clauza FROM, putând fi folosite în cadrul expresiilor.
Operația de redenumire
Redenumirea reprezintă un mecanism utilizat la schimbarea numelor relațiilor sau atributelor. Pentru aceasta se poate folosi clauza AS ce poate să apară atât în clauza SELECT cât și în clauza FROM, sub forma:
Nume_vechi AS nume_nou
Operații cu șiruri
Cele mai frecvente operații făcute cu șirurile de caractere sunt cele în care se folosesc operatorii Like sau Not Like cu scopul regăsirii unor seturi de caractere specificate. Se mai pot folosi și o serie de alte funcții caracter, cum ar fi concatenarea, extragerea subșirurilor, determinarea lungimii unui șir de caractere ș.a.m.d.
Ordonarea afișării înregistrărilor
SQL permite utilizatorului să controleze ordinea de apariție a tuplurilor prin folosirea clauzei ORDER BY. Operația de sortare poate fi foarte costisitoare și trebuie făcută numai în cazuri în care chiar sunt necesare.
Tupluri duplicat
Limbajele formale de interogare se bazează pe relațiile matematice. Din acest motiv, în cadrul relațiilor nu sunt permise înregistrările duplicat dar, deoarece eliminarea acestora este extrem de costisitoare SQL admite duplicatele. Dacă se dorește eliminarea acestora se poate folosi clauza DISTINCT, iar dacă se dorește să se obțină asigurarea că înregistrările duplicat nu sunt eliminate se folosește clauza ALL.
Operații cu mulțimi
SQL folosește în acest caz reuniunea, intersecția și diferența. Prin operația de reuniune se elimină duplicatele dar, dacă nu se urmărește acest lucru se poate folosi clauza UNION ALL. În cazul operației de diferență se poate face precizarea că standardul SQL din 1986 prevedea pentru această operație clauza MINUS, în timp ce standardul din 1992 a redenumit clauza care este folosită astăzi sub denumirea de EXCEPT.
Funcții agregat
SQL poate opera cu funcții pe grupuri de tupluri folosind clauza GROUP BY. Atributele respective sunt folosite pentru a forma grupuri ce au aceleași valori, astfel încât SQL poate determina:
valoarea medie (Avg);
valoarea minimă (Min);
valoarea maximă (Max);
suma totală a valorilor (Sum);
numărul total al înregistrărilor din grup.
Toate aceste funcții sunt denumite funcții agregat sau totalizatoare. Astfel de funcții întorc drept rezultat o singură valoare. Dacă în aceeași interogare apare atât clauza WHERE cât și clauza HAVING, predicatul clauzei WHERE este aplicat primul. Acele tupluri care îndeplinesc condiția impusă se introduc în cadrul unor grupuri cu ajutorul clauzei GROUP BY. Clauza HAVING este aplicată fiecărui grup care se formează. Grupurile ce îndeplinesc condiția impusă prin clauza HAVING sunt utilizate de clauza SELECT pentru a genera tuplurile rezultat. Dacă nu există o clauză HAVING, tuplurile ce îndeplinesc condiția impusă de clauza WHERE sunt tratate ca și cum ar fi un singur grup.
Conceptul de NULL
Interogările în care nu se cunosc toate valorile ce trebuie afișate pun probleme, deoarece o valoare necunoscută nu poate fi comparată sau utilizată ca parte a unei funcții agregat. Toate comparațiile care implică valori necunoscute sunt false prin definiție. Pentru a determina dacă în setul de rezultate se află valori necunoscute se poate utiliza cuvântul cheie NULL în scopul efectuării unui astfel de test. Toate funcțiile agregat, cu excepția funcției COUNT ignoră tuplurile ce au valori necunoscute.
Relații obținute prin cuplare
În cadrul standardului SQL-92 se prevede faptul că fiecare operație de cuplare trebuie să aibe un tip de joncțiune și o condiție de cuplare. Tipurile de joncțiuni prevăzute în standardul respectiv sunt joncțiunile interioare, joncțiunile exterioare stânga, joncțiunile exterioare dreapta și joncțiunile complete exterioare. Cuvintele cheie “interior”, respectiv exterior sunt opționale, deoarece tipul de joncțiune poate fi dedus din joncțiunea propriu-zisă. În standardul SQL-92 se mai introduc alte două noi tipuri de joncțiuni:
joncțiunea încrucișată (o joncțiune interioară fără condiție de cuplare);
joncțiune de uniune (o joncțiune exterioară completă aplicată pe o condiție de cuplare falsă, cum ar fi de exemplu situația în care joncțiunea interioară nu conține nici o înregistrare).
Utilizarea unei condiții de cuplare este obligatorie în cazul joncțiunilor exterioare, dar este opțională în cazul joncțiunilor interioare (dacă se omite, se obține un produs cartezian).
Subinterogări imbricate
Membru al unui set de înregistrări
Pentru a determina acest lucru se pot folosi operatorii In și Not In.
Comparații între seturi de înregistrări
Pentru a compara elementele unei mulțimi se pot folosi operatorii de comparație. Se interzice utilizarea funcțiilor agregat în cadrul altor funcții agregat, astfel încât, de exemplu, nu este acceptată formula Max(Avg()).
Testarea relațiilor ce nu conțin înregistrări
Se face cu ajutorul construcției EXISTS care returnează valoarea True dacă subinterogarea care este folosită ca argument conține înregistrări.
Testarea absenței tuplurilor duplicat
Se face cu ajutorul construcției UNIQUE care întoarce valoarea True dacă subinterogarea din argumentul funcției nu conține tupluri duplicat.
Relații derivate
Standardul SQl-92 permite utilizarea unei subinterogări în cadrul clauzei FROM. Dacă se întâmplă acest lucru, relației rezultat trebuie să i se dea un nume, iar atributele trebuie redenumite.
Modificările bazei de date
Limbajul de manipulare a datelor permite acest lucru, așa cum se va vedea din cele ce urmează.
Ștergeri
Eliminarea tuplurilor din cadrul unei relații se exprimă în mod asemănător unei interogări, cu deosebirea că în locul afișării tuplurilor rezultat, acestea sunt eliminate din cadrul relației respective, așa cum se poate vedea din sintaxa:
DELETE FROM r
WHERE P
Sunt eliminate acele tupluri din relația r care îndeplinesc condiția specificată în predicatul P. Dacă se omite clauza WHERE, sunt eliminate toate tuplurile din cadrul relației. Se pot elimina doar tuplurile dintr-o singură relație la un moment dat, dar se poate asocia un număr nelimitat de relații cu ajutorul unei clauze SELECT-FROM-WHERE ce se poate introduce în cadrul unei clauze WHERE a clauzei DELETE. O astfel de tehnică trebuie însă folosită cu prudență deoarece poate duce la apariția de ambiguități. Se recomandă ca înaintea utilizării clauzei DELETE să se facă toate testele necesare, marcându-se tuplurile ce urmează a fi șterse.
Inserări
Inserarea unei noi înregistrări în cadrul unei relații se face fie prin specificarea unui tuplu, fie prin utilizarea unei interogări al cărei rezultat este setul de tupluri ce urmează a fi inserat. Valorile atributelor tuplurilor inserate trebuie să respecte constrângerile de domeniu impuse.
Înainte de a efectua o operație de inserare se recomandă evaluarea completă a unei instrucțiuni SELECT corespondentă pentru a evita apariția de probleme. Este posibil ca nu toate atributele tuplurilor inserate să aibe valori și, prin urmare, în acest caz acestea trebuie să fie declarate ca fiind necunoscute.
Actualizări
Operația de actualizare permite modificarea anumitor valori în cadrul tuplurilor fără a fi necesară modificarea lor completă. În general, clauza WHERE aplicată clauzei UPDATE poate conține orice construcție corectă acceptată într-o clauză SELECT obișnuită. O clauză SELECT imbricată în cadrul unei clauze UPDATE poate asocia o relație care trebuie actualizată.
1.2.3. Alte caracteristici SQL
SQL face parte din categoria așa-numitelor limbaje de generația a patra datorită puterii sale, a conciziei și a procedurilor de nivel scăzut pe care le conține. Produsele de baze de date conțin un limbaj special ce ajută programatorii de aplicații să creeze șabloane, interfețe utilizator și rapoarte de date. În limbajele de generația a patra nu există un standard unanim acceptat. Standardul SQL-92 definește sesiunile și mediile SQL. Sesiunea SQL reprezintă un concept legat de tehnologia client/server (conectare, deconectare, efectuare sau reluare a tranzacțiilor), în timp ce mediul SQL oferă fiecărui utilizator un identificator și o schemă.
Ca limbaj neprocedural, SQL permite utilizatorilor să precizeze ce trebuie făcut fără a arăta cum trebuie făcut. Cererea făcută de către un utilizator este transformată de sistemul de gestiune a bazei de date în detaliile tehnice necesare obținerii datelor. Din acest motiv, se spune că bazele de date relaționale necesită mult mai puține eforturi de programare decât orice alt tip de baze de date sau sistem de fișiere, ceea ce face ca limbajul SQL să fie relativ ușor de învățat.
1.2.4. Query-By-Example (QBE)
Limbajele de interogare a datelor au fost dezvoltate la începutul anilor șaptezeci când interfețele om-mașină erau, spre deosebire de cele din zilele noastre, limitate și rudimentare. De exemplu, interacțiunea avea loc prin intermediul unor procese alcătuite din seturi de comenzi în care comenzile (cereri de tipul “rulează acest program pe acele date”, “evaluează interogarea” etc.) erau pregătite pe calculatoare separate și puse la un loc în setul de comenzi care era apoi trimis spre procesare. În timp ce avea loc procesarea datelor, între calculator și utilizator nu se producea nici o interacțiune. La terminarea procesului de prelucrare rezultatele erau imprimate, iar utilizatorul le examina pentru a determina următoarea acțiune ce trebuia întreprinsă. Setul de comenzi era apoi reluat până când utilizatorul era mulțumit de rezultat.
Spre deosebire de SQL, limbajul QBE se bazează pe calculul relațional. QBE a fost dezvoltat de M.M. Zloof de la IBM Yorktown Heights Laboratory. În limbajul QBE o interogare este o construcție elaborată pe un terminal interactiv ce afișează imagini bidimensionale ce conțin una sau mai multe relații prezentate sub forma unor formulare care se completează prin introducerea valorilor în coloanele selectate (exemple). Sistemul răspunde la întrebări prin parcurgerea datelor pe baza unui exemplu dat afișând rezultatele pe același ecran. De obicei, reprezentarea relațiilor este ușurată prin intermediul comenzilor interactive care sunt disponibile prin intermediul unor meniuri. Selecția comenzilor din meniu se face în funcție de schema disponibilă, eliminându-se astfel erorile legate de scrierea numelor tabelelor sau atributelor acestora, așa cum s-ar putea întâmpla în cazul folosirii limbajului SQL. Interfața oferită este un editor structurat pe baza unui limbaj grafic.
1.3. SISTEME DE GESTIUNE A BAZELOR DE DATE
Baza de date reprezintă una sau mai multe colecții de date aflate în interdependență împreună cu descrierea datelor și a relațiilor dintre ele.
Colecția de date reprezintă un ansamblu de date organizat după anumite criterii și este format din componentele:
a) o familie de caracteristici alcătuită din atribute ce definesc aspecte ale obiectelor din lumea reală;
b) un predicat aplicat familiei de caracteristici ce conduce la o submulțime ce definește o relație de ordine între caracteristici;
c) o suită temporală T = {t0, t1, …, tj, …} ce definește un decalaj al timpului în intervale discrete;
d) afectarea la fiecare moment tj a unei relații asociată predicatului.
Bazele de date sunt gestionate cu ajutorul unui program numit sistem de gestiune al bazelor de date. Sistemul de gestiune a bazelor de date (SGBD) este un sistem de programe ce permite definirea, crearea și întreținerea bazei de date precum și accesul controlat la acesta.
Din punct de vedere conceptual, gestiunea bazelor de date se bazează pe ideea separării structurii bazei de date de conținutul acesteia. În sistemele de baze de date definirea datelor se separă de programele aplicație, astfel încât utilizatorii văd doar definiția externă a unui obiect fără a cunoaște modul în care e definit acesta și cum funcționează. În acest mod, definiția internă a obiectului poate fi modificată fără a afecta utilizatorii acestuia dacă nu se modifică definiția externă. De exemplu, dacă sunt adăugate noi structuri de date sau sunt modificate cele existente, atunci programele aplicație nu sunt afectate dacă nu depind direct de ceea ce se modifică.
Structura bazei de date reprezintă o colecție de descrieri statice ale tipurilor de entități împreună cu relațiile logice stabilite între ele.
Relațiile logice reprezintă asociațiile dintre mai multe entități.
O entitate este un obiect distinct ce trebuie reprezentat în baza de date.
Un atribut este o proprietate ce descrie un anumit aspect al obiectului ce se înregistrează în baza de date.
Scopul unui sistem de gestiune al unei baze de date este acela de a oferi un mediu care să fie și convenabil, dar și eficient pentru a putea fi folosit la:
extragerea informațiilor din baza de date;
înmagazinarea datelor în baza de date.
Bazele de date sunt de obicei folosite la gestionarea unei mari cantități de date, ceea ce presupune existența următoarelor caracteristici:
definirea structurilor (modelarea datelor);
utilizarea unor mecanisme de manipulare a datelor;
asigurarea securității datelor în baza de date;
asigurarea controlului concurenței în cazul utilizării sistemului de către mai mulți utilizatori
Orice sistem de gestiune al bazelor de date are următoarele componente:
Limbajul de definire a datelor
Cu ajutorul acestui limbaj se specifică tipurile de date și structurile precum și constrângerile asupra datelor. Instrucțiunile limbajului sunt compilate și transformate într-un set de tabele înmagazinate într-un fișier special numit dicționar de date sau catalogul sistemului (descrierea datelor se întâlnește sub denumirile de catalog de sistem, dicționar de date sau meta-date ceea ce înseamnă date despre date). Structura de înmagazinare a datelor precum și metodele de acces utilizate de sistemul bazei de date sunt specificate cu ajutorul unui set de definiții folosit cu scopul ascunderii detaliilor de implementare a schemelor bazei de date
Un limbaj de manipulare a datelor
Acest limbaj este folosit pentru a ajuta utilizatorul să acceseze și să folosească datele aflate în baza de date într-un mod interactiv. Cu ajutorul acestui limbaj se pot:
extrage date din baza de date;
introduce date în baza de date;
elimina date din baza de date;
actualiza date din baza de date.
Administratorul bazei de date
Administratorul bazei de date este un program ce asigură interfața dintre datele înmagazinate, aplicațiile care folosesc aceste date și întrebările adresate sistemului cu ajutorul cărora se extrag datele necesare. De obicei, bazele de date necesită un spațiu mare de înmagazinare pe mediul de stocare ales, ce poate ajunge de ordinul gigabytes-ilor. Pentru a putea fi prelucrate datele se transferă din memoria externă în memoria internă a sistemului. Scopul sistemului bazei de date este acela de a ușura accesul la date, iar administratorul bazei de date este răspunzător de următoarele:
asigură interacțiunea cu administratorul de fișiere (trebuie să transfere instrucțiunile limbajului de manipulare a datelor în comenzi de nivel scăzut recunoscute de sistemul de fișiere);
asigură integritatea datelor prin verificările pe care le efectuează în momentul actualizării datelor astfel încât acestea să nu încalce constrângerile impuse și să fie consistente;
asigură securitatea datelor prin accesul controlat la date pe care îl oferă utilizatorilor (aceștia nu pot accesa orice fel de date dacă nu le este permis acest lucru);
creează copiile de siguranță și asigură refacerea datelor, în cazul apariției unei erori sau defecțiuni în baza de date, la starea la care acestea se aflau înainte de apariția erorii sau defecțiunii;
asigură controlul concurenței păstrând consistența datelor atunci când acestea sunt accesate în același timp de mai mulți utilizatori.
1.3.1. Componentele unui sistem de gestiune al bazelor de date
Acestea sunt:
1. Hardware
2. Software
3. Date
4. Proceduri
5. Resurse umane
1.3.1.1. Componenta hardware
Această componentă poate fi reprezentată de un singur calculator personal, un singur calculator mainframe sau o rețea de calculatoare.
De obicei, într-o rețea de calculatoare, se aplică următoarea schemă:
Se folosește un calculator principal pe care se află programele back-end – adică partea din sistemul de gestiune al bazei de date care administrează și controlează accesul la baza de date și mai multe calculatoare aflate în diferite locații pe care se află programele front-end – adică partea din sistemul de gestiune al bazei de date ce constituie interfața cu utilizatorul.
În această schemă, numită client-server, programele back-end reprezintă serverul iar cele front-end reprezintă clienții.
1.3.1.2. Componenta software
Această componentă este alcătuită din:
programele sistemului de gestiune al bazei de date;
programele aplicație scrise de obicei în limbaje de programare de generația a III-a (C, Pascal, Cobol) sau SQL încorporat într-un limbaj de generația a III-a;
sistemul de operare;
programe de rețea.
Sistemul de gestiune al bazei de date poate avea încorporate instrumente din generația a IV-a, cum ar fi SQL ce permit:
• dezvoltarea rapidă de aplicații;
• îmbunătățirea semnificativă a productivității;
• realizarea unor programe ușor de întreținut.
1.3.1.3. Date
Datele acționează ca o punte de legătură între componentele mașină (hardware și software) și componenta umană. Baza de date conține atât datele operaționale (setul de înregistrări pe care se lucrează) cât și metadatele. Structura bazei de date este numită schemă.
1.3.1.4. Proceduri
Procedurile reprezintă instrucțiunile și regulile aplicate în proiectarea și utilizarea bazei de date.
Acestea pot fi:
deschiderea unei sesiuni de lucru în sistemul de gestiune al bazei de date;
pornirea sau oprirea sistemului de gestiune al bazei de date;
utilizarea unui program de aplicație sau a unei funcții a sistemului de gestiune al bazei de date;
efectuarea de copii de siguranță;
tratarea defecțiunilor hardware și software;
modificarea structurii unui tabel, reorganizarea bazei de date, îmbunătățirea performanțelor, arhivarea datelor.
1.3.1.5. Resursele umane
Resursele umane sunt reprezentate de:
1. Administratorul de date este responsabil de gestionarea resurselor de date și proiectarea conceptual / logică a bazei de date.
2. Administratorul bazei de date este responsabil de realizarea fizică a bazei de date ce implică proiectarea și implementarea acesteia. Administratorul bazei de date este o persoană care are în răspundere controlul centralizat al datelor și al aplicațiilor ce folosesc aceste date. Îndatoririle administratorului bazei de date cuprind:
definește schema bazei de date, ceea ce presupune scrierea unui set de definiții în limbajul de definire a datelor care apoi să poată fi compilate de către un compilator DDL și transformate într-un set de tabele păstrate în catalogul sistemului;
definește structura de stocare și a metodele de acces prin scrierea unui set de definiții transferate compilatorului;
modifică schema și organizarea fizică prin scrierea unui set de definiții utilizate de către compilatorul DDL pentru a face modificările cerute în tabele;
asigură securitatea prin acordarea drepturilor de acces utilizatorilor pe baza unor conturi de utilizator create în acest scop;
verifică respectarea constrângerilor de integritate ori de câte ori se introduc date în baza de date;
monitorizează toate activitățile utilizatorilor;
monitorizează creșterea dimensiunilor bazei de date;
își formează o imagine de ansamblu asupra sistemului, urmărind părțile tari și slabe ale acestuia;
asigură controlul concurenței prin alegerea tipului de blocare ce va fi folosit atunci când aceleași date sunt folosite de mai mulți utilizatori în același timp;
asigură fiabilitatea sistemului în cazul apariției unor erori.
Proiectanții de baze de date care pot fi:
Proiectant de baze de date logice:
identifică datele (entități și atribute);
identifică relațiile dintre date;
identifică constrângerile;
identifică regulile ce descriu principalele caracteristici ale datelor;
implică utilizatori în realizarea modelului de date.
Proiectant de baze de date fizice:
transpune modelul logic într-un set de tabele și constrângeri;
selectează structuri de stocare și metode de acces specific;
asigură securitatea datelor.
Utilizatorii finali care pot fi de următoarele categorii:
Programatorii de aplicații. Aceștia sunt profesioniștii ce interacționează cu sistemul folosind instrucțiuni scrise în limbajul de manipulare a datelor pe care le încorporează în cadrul unor interfețe create în alte limbaje de programare. Precompilatorul DML convertește apelurile scrise în limbajul de manipulare a datelor în proceduri specifice limbajului gazdă. Compilatorul limbajului gazdă generează apoi codul obiect.
Utilizatori cu pregătire specială. Aceștia interacționează cu sistemul fără a scrie programe, dar ei formulează cereri pentru a extrage date din baza de date cu ajutorul instrucțiunilor specifice limbajului de manipulare a datelor. Aceste cereri sunt transmise procesorului de interogare care desparte o instrucțiune specifică limbajului de manipulare a datelor în instrucțiuni specifice modulului de administrare a bazei de date.
Utilizatori specializați. Aceștia sunt utilizatori cu pregătire specială care scriu programe aplicație specializate pentru diverse zone de interes (sisteme CAD, sisteme expert etc.).
Utilizatori obișnuiți. Aceștia sunt utilizatori care interacționează cu sistemul folosind interfețele create de programatorii de aplicații.
1.3.2. Componentele unui sistem de gestiune a bazelor de date
Sistemele de gestiune a bazelor de date sunt alcătuite dintr-o serie de module ce îndeplinesc diverse funcționalități. Anumite funcționalități sunt îndeplinite împreună cu sistemul de operare pe care este folosit sistemul respectiv. Principalele componente ale unui sisteme de gestiune al bazelor de date sunt:
Administratorul de fișiere gestionează alocarea spațiului pe disc precum și structurile de date utilizate la reprezentarea datelor pe disc. Acesta transmite cererea către metoda de acces corespunzătoare care fie citește datele din buffer-ul sistemului, fie le scrie în acesta.
Administratorul bazei de date acceptă interogările și examinează schemele externe și conceptuale pentru a determina ce înregistrări sunt necesare pentru a satisface o anumită cerere, după care apelează administratorul de fișiere pentru a efectua cererea.
Procesorul de interogare transformă interogările într-o serie de instrucțiuni de nivel jos adresate administratorului de baze de date.
Preprocesorul DML convertește instrucțiunile DML dintr-un program aplicație în apeluri de funcții standard ale limbajului gazdă și interacționează cu procesorul de interogare pentru a genera codul corespunzător.
Figura 1.3. Componentele bazei de date
Compilatorul DDL transformă instrucțiunile DDL într-un set de tabele ce conțin meta-datele. Tabelele sunt stocate în catalogul sistemului.
Administratorul de catalog gestionează accesul și întreținerea catalogului sistem. Catalogul sistemului este accesat de majoritatea componentelor sistemului de gestiune al bazei de date.
Una dintre cele mai importante funcții din cadrul sistemului de gestiune al bazelor de date o are administratorul bazei de date. Acesta păstrează interfața cu programele aplicație și interogările lansate de utilizatori.
Figura 1.4. Componentele administratorului bazei de date
Administratorul bazei de date are una dintre cele mai importante funcții în cadrul unui sistem de gestiune al bazelor de date. Principalele componente ale acestuia sunt prezentate în figura 1.4. Aceste componente pot fi următoarele:
Procesorul de interogare este utilizat pentru a simplifica și ușura accesul la date. Acesta conține Evaluatorul de interogare care execută fiecare interogare pe baza unui plan.
Administratorul de date este utilizat pentru a minimiza resursele necesare transferului de date dintre memoria internă și cea externă. Administratorul de date este un program care oferă o interfață între datele înmagazinate în baza de date și interogările formulate prin intermediul aplicațiilor. Conține următoarele componente:
Controlul de autorizare care verifică dacă utilizatorul are dreptul de a efectua operația cerută.
Administratorul de fișiere.
Administratorul de buffer care răspunde de transferul datelor dintre memoria principală și dispozitivele de stocare secundare.
Administratorul de tranzacții este utilizat pentru a controla atomicitatea și concurența tranzacțiilor în scopul păstrării consistenței și durabilității bazei de date. O tranzacție reprezintă o colecție de operații aplicate bazei de date care sunt efectuate toate deodată sub forma unei singure unități logice. Această componentă este alcătuită din:
Administratorul de tranzacții.
Administratorul de blocare.
Administratorul de reconstituire care garantează că baza de date rămâne într-o stare coerentă după ce în baza de date a apărut o eroare. Acesta este responsabil de reluarea sau abandonarea unei tranzacții.
1.3.3. Funcțiile sistemelor de gestiune a bazelor de date
Stocarea, regăsirea și reactualizarea datelor.
Este funcția fundamentală a unui sistem de gestiune a bazelor de date. Sistemul trebuie să ascundă față de utilizatori detaliile privind implementarea fizică internă.
Asigurarea unui catalog accesibil utilizatorului
Catalogul sistemului conține date despre scheme, utilizatori, aplicații. Acesta trebuie să stocheze:
denumirile, tipurile și dimensiunile articolelor de date;
denumirile relațiilor;
constrângerile de integritate asupra datelor;
numele utilizatorilor autorizați care au acces la date;
schemele externe, conceptuale, interne precum și transpunerile lor;
statistica utilizării (de exemplu: frecvența tranzacțiilor, contorizarea numărului de accesări ale obiectelor din baza de date).
Utilizarea unui astfel de catalog de sistem asigură o serie de avantaje care sunt prezentate în continuare:
contribuie la controlul datelor ca resurse;
se poate defini în sensul datelor;
simplifică comunicarea;
identifică utilizatorii;
identifică cu ușurință redundanța și incoerența;
înregistrează modificările din baza de date;
impactul unei modificări poate fi determinat înainte de implementare;
îmbunătățește securitatea;
îmbunătățește integritatea;
monitorizează operațiile efectuate asupra bazei de date.
Asigurarea tranzacțiilor
Tranzacția reprezintă un set de acțiuni prin care se accesează sau se modifică conținuturile bazei de date. Dacă tranzacția eșuează (nu s-au efectuat toate modificările, sau modificările nu s-au efectuat în toate cazurile) baza de date devine incoerentă și, ca urmare, trebuie avut în vedere un mecanism care să anuleze toate modificările efectuate în cadrul tranzacției și să aducă baza de date în ultima stare coerentă anterioară începerii tranzacției.
Asigurarea serviciilor de control concurente
Sistemul de gestiune al bazei de date trebuie să garanteze că nu vor avea loc interferențe atunci când mai mulți utilizatori accesează baza de date.
Asigurarea serviciilor de reconstituire
În cazul în care în timpul funcționării sistemului au avut loc defecțiuni de natură hardware sau software, acesta trebuie readus într-o stare coerentă.
Asigurarea serviciilor de autorizare
În cazul în care în timpul funcționării utilizatorii încearcă intenționat sau accidental să acceseze date pe care nu au dreptul să le prelucreze, sistemul de gestiune al bazei de date trebuie să intervină.
Asigurarea unui suport pentru comunicarea datelor
Utilizatorii trebuie să poată accesa o bază de date centralizată de la locații aflate la distanță.
Asigurarea serviciilor de integritate
Integritatea bazei de date se referă la corectitudinea și coerența datelor stocate și se exprimă sub forma unor constrângeri care reprezintă regulile de coerență pe care baza de date nu are voie să le încalce.
Asigurarea serviciilor pentru promovarea independenței de date
Independența de date este obținută printr-un mecanism de vedere sau subschemă. Completa independență logică de date este dificil de obținut. De obicei se pot adăuga entități, atribute, relații, dar eliminarea lor nu este întotdeauna posibilă.
Asigurarea de servicii utilitare
Serviciile utilitare ajută la administrarea bazei de date. Câteva astfel de exemple sunt următoarele:
facilități de import;
facilități de monitorizare, pentru urmărirea utilizării;
programe de analiză statistică;
facilități de reorganizare a indecșilor;
compactarea și realocarea spațiului eliberat prin îndepărtarea unor înregistrări din dispozitivele de stocare.
2. Modelarea datelor
2.1. Modele de date: rețea, ierarhice, relaționale, obiectuale, hibrid
Înaintea construirii unei baze de date este necesară elaborarea unui model de date utilizat pentru reprezentarea datelor. Un astfel de model se dovedește a fi de mare ajutor la înțelegerea datelor și la luarea celor mai bune decizii de proiectare în cadrul modelului fizic.
Un model este o abstractizare și o structură ce simbolizează toate caracteristicile entităților esențiale ce prezintă interes pentru utilizator, o reprezentare și o reflectare a lumii reale (Universul Discursului).
Un model de date reprezintă o colecție integrată de concepte necesare descrierii datelor, relațiilor dintre ele, precum și a constrângerilor asupra datelor (Connolly ș.a. 1998). Modelul de date este utilizat la descrierea schemei bazei de date, definind structura datelor, legăturile dintre acestea, semantica lor, precum și constrângerile impuse, deși nu este obligatoriu ca întotdeauna acestea să fie regăsite în orice model de date. Pe scurt, un model de date este utilizat pentru a reprezenta date despre date.
Modelele de date oferă înțelegerea descriptivă necesară definirii schemelor logice și externe și sunt utile descrierii formale a schemei bazei de date.
Schema logică a unei baze de date reprezintă o descriere abstractă a unei porțiuni din realitatea modelată împreună cu instanțele bazei de date.
Un model de date este alcătuit din trei elemente de bază:
entități;
atribute;
relații.
O entitate reprezintă un obiect sau concept din lumea reală, cum ar fi de exemplu un student sau un curs descris în cadrul bazei de date.
Un atribut reprezintă acele caracteristici ce descriu aspecte sau condiții ale unei entități, cum ar fi de exemplu numele studentului sau situația acestuia.
Relația stabilită între două sau mai multe entități reprezintă o interacțiune între acele entități, cum ar fi de exemplu asocierea dintre un student și cursul pe care îl urmează.
Așa cum arătau Elmasri și Navathe, modelele de date ajută la înțelegerea datelor “asociate logic”.
2.1.1. Istoricul bazelor de date
În continuare se vor prezenta câteva dintre cele mai importante evenimente petrecute pe parcursul dezvoltării bazelor de date.
În anul 1961 Charles Bachman proiectează Integrated Data Store (IDS) – predecesorul modelului rețea.
Spre sfârșitul anilor ’60, IBM creează “Information Management System: IMS” bazat pe modelul ierarhic.
Spre sfârșitul anilor ’60, grupul CODASYL (Committee for Data System Languages) definește /standardizează modelul rețea.
În 1969 Edgar Codd cercetător la firma IBM construiește modelul relațional.
În ani ’70 apar SEQUEL (SQL), QBE; QUEL, System R (DB2), Ingres.
În anul 1976, Peter Chen construiește modelul Entitate-Relație.
În anii ’80 apar sistemele de gestiune a bazelor de date printre care: DB2, Oracle, Sybase, Informix, DBase, Paradox.
În anul 1986 a fost definit primul standard SQL.
Între anii 1990 și 2000 apar concepte precum OODB, ORDB (Postgres), Data Warehouse, OLAP, Data Mining, GIS, Mobile DB, Multimedia DB, Web DB, XML DB.
Inabilitatea bazelor de date de a lucra eficient în cadrul fișierelor obișnuite cu date ce implică utilizarea grupurilor repetitive de date a condus la dezvoltarea unei mari varietăți de structuri de baze de date, numite de obicei și modele de baze de date.
2.1.2. Funcțiile modelelor
Funcțiile modelelor sunt:
Reprezintă obiecte, evenimente precum și asocierile dintre acestea.
Reprezintă aspecte esențiale și inerente, ignorând proprietățile accidentale.
Au în vedere ansamblul entităților, atributelor și relațiilor dintre acestea.
Asigură regulile de bază și relațiile ce permit proiectanților și utilizatorilor să comunice corect, fără ambiguități.
Un model de date este alcătuit din următoarele componente:
Partea structurală ce reprezintă un set de reguli ce fundamentează baza de date.
Partea de manipulare ce definește tipurile de operații ce se pot efectua în baza de date:
operații utilizate pentru actualizarea sau regăsirea datelor;
operații utilizate pentru modificarea structurii bazei de date.
Set de reguli de integritate ce garantează faptul că datele sunt corecte.
Există trei modele de baze de date:
Modelul de date extern utilizat pentru a reprezenta vederea fiecărui utilizator, care mai este cunoscut și sub denumirea de Univers al Discursului. Acest model este reprezentat prin modelele de date bazate pe înregistrări.
Modelul de date conceptual care reprezintă vederea logică independentă de sistemul de gestiune al bazelor de date ales și reprezentat prin modelele de date bazate pe obiecte.
Modelul de date intern utilizat pentru ca schema conceptuală să poată fi înțeleasă de către sistemul de gestiune al bazei de date și reprezentat prin modelele de date fizice.
Fiecare model de date are propria reprezentare a datelor, dar întotdeauna un model este alcătuit dintr-o intensie și o extensie.
Extensia unei relații se referă la setul curent de înregistrări pe care îl conține. Acest set de înregistrări nu rămâne același tot timpul existenței bazei de date, suferind diverse modificări, pe măsura introducerii, actualizării sau ștergerii de date.
Partea cu caracter permanent în cadrul unei baze de date o reprezintă intensia sa sau schema bazei de date. Intensia bazei de date descrie structura tuplurilor unei relații. Operațiile limbajului de manipulare a datelor pot fi efectuate numai în condițiile în care se cunoaște această structură.
Cu alte cuvinte intensia unei baze de date reprezintă tipurile de entități, fiind considerată a fi modelul conceptual al bazei de date, pe când extensia reprezintă instanțierile tipurilor de înregistrări corespunzătoare tipurilor de entități precum și legăturile dintre acestea.
2.1.3. Modele de date bazate pe înregistrări
Astfel de modele descriu datele la nivel conceptual. Spre deosebire de modelele orientate pe obiecte, acestea sunt folosite cu scopul de a specifica structura logică generală a bazei de date și de a oferi un nivel ridicat al descrierii implementării. Modelele sunt denumite în acest fel deoarece baza de date este alcătuită din înregistrări de același tip. Fiecare tip de înregistrare are un număr fix de câmpuri, fiecare câmp având, de obicei, o lungime fixă, ceea ce duce la simplificarea reprezentării. Aceste modele nu oferă un mecanism de reprezentare directă a codului din baza de date. Pentru a efectua interogări și actualizări asupra bazei de date se folosesc o serie de limbaje individuale separate asociate modelului. Din această categorie de modele fac parte:
modelul de date ierarhic;
modelul de date rețea;
modelul de date relațional.
Astăzi, datorită dezvoltării fără precedent a Internetului, din ce în ce mai mult, se impune un alt tip de model, modelul de date semi-structurat, în format XML.
Modelul ierarhic
Din punct de vedere istoric, acesta a fost primul model de date ce a fundamentat un sistem de gestiune al bazelor de date și a fost dezvoltat de către firma IBM pentru produsul său IMS care utiliza limbajul DL/1.
Modelul ierarhic lucrează cu grupuri repetitive prin utilizarea unei structuri de date ce se bazează pe parcurgerea de sus în jos a unui arbore: datele aflate în înregistrările primare reprezintă ramurile arborelui, în timp ce datele ce formează grupurile repetitive reprezintă frunzele acestuia.
Avantajul modelului ierarhic este acela că metodele folosite la regăsirea înregistrărilor asociate din baza de date sunt mai simple decât cele folosite în modelul rețea.
Intensia modelului de date ierarhic este reprezentată cu ajutorul unui arbore de definiție ce reprezintă o diagramă a structurii de date în care sensul legăturilor funcționale este întotdeauna de la nodul părinte către nodul copil. O astfel de diagramă este un graf orientat alcătuit cu scopul reprezentării tipurilor de entități și a relațiilor dintre acestea. Nodurile grafului corespund tipurilor de entități, iar arcele grafului reprezintă legăturile funcționale dintre tipurile de entități.
Extensia modelului de date ierarhic se reprezintă sub forma unui tabel în care fiecare linie a tabelului este o înregistrare ce corespunde unei instanțieri a tipului de entitate. În tabele sunt permise duplicatele și, prin urmare, pot exista două instanțieri identice ale aceluiași tip de entitate. Un singur tabel din baza de date are rolul de rădăcină a arborelui în timp ce restul tabelelor formează mulțimea părinților și copiilor arborelui.
Figura 2.1. Modelul ierahic
O relație într-o bază de date ierarhică este reprezentată prin intermediul perechii părinte/copil. În acest tip de relație, tabelul părinte poate fi asociat cu unul sau mai multe tabele copil, dar un singur tabel copil poate fi asociat doar cu un singur tabel părinte. Aceste tabele sunt asociate în mod explicit cu ajutorul unor pointeri sau pe baza unui aranjament fizic al înregistrărilor în tabele.
Utilizatorul accesează datele pornind din rădăcina arborelui și parcurge un anumit drum unic până ajunge la datele căutate. O astfel de metodă de acces cere utilizatorului o foarte bună cunoaștere a structurii bazei de date.
Un avantaj al utilizării bazelor de date ierarhice este acela că utilizatorul poate extrage datele foarte rapid datorită legăturilor explicite definite în structura tabelelor. Un alt avantaj este acela că integritatea referențială se obține prin crearea structurii și nu poate fi încălcată, ceea ce face ca o înregistrare din tabelul copil să fie obligatoriu asociată unei înregistrări existente în tabelul părinte, iar o înregistrare ștearsă din tabelul părinte să impună eliminarea tuturor înregistrărilor asociate din tabelul copil.
Probleme deosebite vor apare în momentul în care utilizatorul dorește să introducă o înregistrare în tabelul copil care nu are asocieri cu nici o înregistrare din tabelul părinte. Acest tip de bază de date nu poate suporta asocierile complexe și, de aceea, deseori sunt probleme referitoare la redundanța datelor, deoarece este posibil să-i fie permisă introducerea de date inconsistente. Această problemă poate fi însă rezolvată prin crearea a două baze de date pentru a înlocui tipurile de relații mulți-la-mulți, așa cum se prezintă în figura de mai jos:
Figura 2.2. Rezolvarea relațiilor mulți-la-mulți
Deși bazele de date ierarhice ofereau un acces direct și rapid la date, dovedindu-și superioritatea într-o multitudine de situații specifice, devenise evident că era necesară introducerea unui nou model de date pentru a remedia problemele tot mai presante referitoare la redundanța datelor și la rezolvarea asocierilor complexe dintre înregistrări.
Modelul rețea
Modelul rețea a fost creat, în special, ca o încercare de a rezolva unele dintre problemele modelului ierarhic.
Figura 2.3. Modelul rețea
Așa cum se poate observa din figura 2.3., structura unei baze de date de tip rețea se poate reprezenta cu ajutorul conceptelor de noduri și seturi. Un nod reprezintă o colecție de înregistrări, în timp ce un set stabilește și reprezintă relațiile din cadrul unei bazei de date de tip rețea. O astfel de construcție transparentă relaționează o pereche de noduri prin utilizarea unuia dintre ele sub denumirea de proprietar, iar a celuilalt sub denumirea de membru.
Structura de tip set este o construcție ce stabilește și reprezintă o relație din cadrul bazei de date rețea (reprezintă o îmbunătățire remarcabilă față de relația părinte/copil). O astfel de structură suportă o relație de unu-la-mulți, ceea ce înseamnă faptul că o înregistrare din nodul proprietar poate fi relaționată cu una sau mai multe înregistrări aparținătoare nodului membru, dar unei singure înregistrări din nodul membru îi este asociată o singură înregistrare din nodul proprietar. Mai mult decât atât, o înregistrare aparținătoare nodului membru nu poate exista fără să fie asociată unei înregistrări existente în nodul proprietar.
Între o pereche de noduri se pot defini unul sau mai multe seturi, iar un singur nod poate fi implicat în seturi cu alte noduri din baza de date. Utilizatorul poate accesa date din cadrul unei baze de date de tip rețea prin cea mai potrivită structură de seturi. Spre deosebire de bazele de date ierarhice, în care accesul trebuie să înceapă cu nodul rădăcină, în bazele de date de tip rețea utilizatorul poate accesa datele indiferent de nod pe baza structurilor de tip set.
CODASYL a dezvoltat limbajul Common Business-Oriented Language (COBOL) pentru a scrie aplicații ce folosesc datele din bazele de date de tip rețea. Cu toate dezavantajele pe care le are, modelul de baze de date propus de CODASYL mai are și astăzi o largă răspândire în întreaga lume.
Bazele de date CODASYL folosesc în locul termenului de tabel, termenul de tip de înregistrare, dar caracteristicile acestuia nu diferă cu nimic față de cele ale unui tabel. Tipurile de înregistrări conțin pointeri la înregistrările provenite din alte tipuri de înregistrări. Un pointer este o valoare ce specifică locația unei înregistrări într-un fișier sau în memorie. De exemplu, înregistrarea ce conține date referitoare la un student, conține un pointer la o notă a acestuia, care în replică va conține un pointer la o altă notă ce aparține acelui student, ș.a.m.d. Termenul generic utilizat la descrierea tipurilor de înregistrări bazate pe pointeri este lista de legătură. Pointerii asociază înregistrările într-o structură organizată, numită rețea.
Bazele de date de tip rețea au performanțe excelente în cazul regăsirii seturilor de înregistrări ce aparțin unui anumit obiect, deoarece relațiile dintre înregistrări (pointeri) reprezintă parte constitutivă a bazei de date. În același timp, se permite utilizatorilor crearea de interogări mult mai complexe decât cele ce se pot elabora prin intermediul bazelor de date ierarhice, dar viteza bazelor de date de tip rețea scade atunci când se dorește căutarea înregistrărilor pe baza unor criterii specificate. Principalul dezavantaj al acestui tip de baze de date este legat de faptul că utilizatorul este obligat să cunoască foarte bine structura bazei de date pentru a se putea descurca cu structurile de seturi. Totodată, aplicațiile ce lucrează cu astfel de baze de date (în principal programele COBOL) trebuie să actualizeze atât valorile datelor cât și pointerii înregistrărilor ce se adaugă, șterg sau se modifică. Necesitatea actualizării secvențiale atât a datelor cât și a pointerilor duce la creșterea complexității proceselor în care sunt implicate tranzacții.
Un alt dezavantaj este acela că nu este ușoară modificarea structurii bazei de date fără a afecta programele aplicație care lucrează cu aceasta. Deoarece, așa cum s-a arătat, o relație este definită în mod explicit sub forma unei structuri de tip set, aceasta nu poate fi modificată fără a afecta programele aplicație ce folosesc această structură la căutarea datelor. Dacă se modifică o astfel de structură, trebuie modificate în mod corespunzător toate asocierile acesteia definite în programele aplicație.
Intensia modelului de baze de date de tip rețea este un graf cu arce numerotate pentru a indica drumul ce trebuie parcurs, deoarece un tip de entitate copil poate fi conectat la mai multe tipuri de entități părinte sau la același tip de entitate părinte prin mai multe arce.
Extensia acestui model este un tabel ce permite introducerea de înregistrări duplicat, dar înregistrările pot fi ordonate.
Modelul relațional
Acesta este cel mai folosit model de date folosit astăzi în întreaga lume, fiind un model de tip entitate-relație bazat pe elaborarea unui model conceptual. Modelul relațional al unei baze de date permite extinderea bazelor de date la nivelul calculatoarelor personale nemaifiind obligatorie utilizarea echipamentelor costisitoare cerute de minicalculatoare sau de calculatoarele de tip mainfraime.
Modelul a fost dezvoltat de către Dr. E. F. Codd de la San Jose Research Laboratories ce aparțineau firmei IBM în anul 1970. Cele mai importante caracteristici ale modelului relațional sunt simplitatea, suportul teoretic solid, precum și cele trei elemente componente de bază.
Un astfel de model este simplu deoarece el poate fi descris cu ajutorul unui număr mic de concepte care se referă la relații (structuri de date bidimensionale ce au proprietăți speciale), rânduri (datele aflate în cadrul relațiilor), coloane (câmpurile datelor din rândurile corespunzătoare) și chei (mecanismul de identificare și asociere a rândurilor aflate în unul sau mai multe tabele).
Modelul relațional are un suport teoretic foarte solid deoarece se bazează pe teoria matematică a seturilor, ceea ce înseamnă faptul că toate operațiile sunt încheiate cu succes, iar rezultatele operațiilor sunt predictibile.
Cele trei componente ale modelului relațional sunt:
componenta de structură a datelor (relații cu proprietăți speciale);
componenta de manipulare a datelor (operații predefinite prin care tehnologia relațională folosește un optimizator inteligent pentru a găsi calea de acces la date);
componenta de integritate a datelor (reguli necesare protecției datelor la efectuarea unor operații incorecte).
Principalul avantaj al modelului relațional este acela că nu este necesară utilizarea atât a pointerilor cât și a datelor în cadrul tabelelor, folosind în schimb relații pentru a accesa valori corespondente din mai multe tabele.
O relație constă dintr-o asociere între înregistrările aflate în două tabele ce au aceleași valori ale atributelor. Deoarece tabelele relaționale nu conțin pointeri, datele aflate în astfel de tabele sunt independente de metodele folosite de către sistemul de gestiune al datelor în lucrul cu înregistrările tabelelor.
Intensia modelului relațional este o schemă relațională cu una sau mai multe scheme de relație. Fiecare schemă de relație are propriul nume și propriile atribute.
Extensia modelului relațional este un tabel ce nu permite înregistrări duplicat. Fiecare schemă de relație introduce un tabel în schema relațională. Modelul de date relațional folosește tabele bidimensionale ce reprezintă entitățile și constă din rânduri și coloane. O coloană reprezintă un atribut al unei entități ce mai poartă și denumirea de câmp sau proprietate. Un rând reprezintă un tuplu care este o instanță a unui tip de entitate sau de relație sau orice altceva din baza de date. De obicei una dintre coloanele tabelului este numită cheie primară și are o valoare unică (Brown, The Relational Model).
Simplitatea modelului bazei de date relaționale constă din simplitatea conceptelor cu care operează: structuri simple și abstracte de date, independența fizică de date, cadrul puternic, general și realist oferit aplicațiilor ș.a.m.d.
Modelul relațional oferă o interfață flexibilă ce este prevăzută cu cele mai potrivite componente necesare oricărui utilizator la toate nivelele, oferind o mare independență a datelor (produsul obținut este relativ independent de implementarea internă).
Baza de date relațională constă din unul sau mai multe relații sau tabele. Principalele concepte ale modelului relațional sunt:
Atributul – este o coloană ce are un nume propriu și unic într-o relație (câmp). Fiecare relație conține o listă de atribute (sau coloane) definite pe un anumit domeniu.
Domeniul – reprezintă setul posibil de valori pe care îl poate avea unul sau mai multe atribute. Utilizatorul poate defini domeniul de definiție, dar numai în anumite produse își poate defini propriile domenii.
Tuplu – un rând din cadrul unei relații (înregistrare). Un rând dintr-un tabel reprezintă asocierea dintre seturile de valori. Fiecare relație conține un set de tupluri (sau rânduri).
Intensia – structura unei relații împreună cu specificațiile și constrângerile de domeniu aplicate. Se modifică rar.
Extensia – starea relației (valorile din cadrul unei relații se pot modifica). Reprezintă conținutul curent al bazei de date ce corespunde schemei bazei de date și se modifică frecvent.
Gradul – numărul de atribute dintr-o relație.
Cardinalitatea – numărul de tupluri dintr-o relație.
Baza de date relațională – reprezintă o colecție de relații ce pot fi modificate (tabele). O astfel de colecție este descrisă sub forma unui set de scheme de relații din cadrul bazei de date, numite scheme relaționale ale bazei de date. Relațiile sunt alcătuite din două părți:
instanța – un tabel cu rânduri și coloane;
schema – specifică numele relației împreună cu numele și tipul fiecărei coloane.
Termenul de relație este folosit în sensul său matematic acceptat:
Se dă o schemă de relație R = r(A1, …, An) pe un set de domenii {D1, D2…, Dn}. O relație n-ară r reprezintă un subset al produsului cartezian al acestor domenii: D1 x D2 x … x Dn.
Proprietățile unei relații sunt:
relațiile sunt alcătuite din rânduri și coloane;
într-o relație nu are importanță ordinea de apariție a rândurilor sau coloanelor;
între tabele nu există o asociere explicită (nici una vizibilă cuiva care accesează datele);
fiecare înregistrare poate fi identificată în mod unic;
fiecare rând din cadrul unui tabel are același set de coloane;
fiecare coloană are un singur tip de dată (nu sunt acceptate redefiniri pentru diferite valori).
Datorită acestor proprietăți și a fundamentului matematic, modelul relațional permite proiectanților concentrarea mai întâi asupra semanticii datelor și a relațiilor dintre ele și abia apoi asupra implementarii fizice a semanticii respective pentru a se adapta cât mai bine cerințelor și specificațiilor impuse.
2.1.4. Modele logice orientate pe obiecte
Descriu datele la nivelele conceptual și extern oferind o flexibilitate ridicată. Astfel de modele pot specifica în mod explicit constrângerile aplicate datelor și se bazează pe următoarele concepte:
entitate – un obiect sau concept din lumea reală ce are identitate proprie;
atribut – un set de proprietăți utilizate la descrierea entităților;
relație – o asociere între două sau mai multe entități.
Din această categorie fac parte:
modelul entitate-relație;
modelul orientat pe obiecte;
modelul obiectual-relațional;
modelul binar;
modelul semantic de date;
modelul infologic;
modelul funcțional de date.
Dintre acestea se remarcă modelele următoare:
Modelul entitate-relație
Se bazează pe o percepție a lumii reale ca fiind alcătuită dintr-o colecție de obiecte de bază sau concepte (entități) împreună cu relațiile care se stabilesc între ele. Fiecare entitate are asociat un set de atribute care o descriu, iar o relație reprezintă o asociere dintre două sau mai multe entități. Mulțimile tuturor entităților sau relațiilor de același tip sunt cunoscute sub denumirea de tipuri de entități sau relații. Un alt element important în cadrul diagramelor entitate-relație îl reprezintă precizarea constrângerilor de cardinalitate care exprimă numărul de entități asociate altui tip de entitate prin intermediul unui tip de relație.
Modelul orientat pe obiecte
Un astfel de model este utilizat doar în scopuri speciale, cele mai cunoscute produse de acest tip fiind: ObjectStore, Gemstone, Ontos, O2, Jasmine, Cache. Modelul se bazează pe o colecție de obiecte, la fel ca în cazul modelului entitate-relație.
Un obiect conține valorile înmagazinate în cadrul unor variabile instanțiate în interiorul acestor obiecte. Spre deosebire de modelul entitate-relație, valorile sunt ele însele obiecte. Astfel de obiecte conțin alte obiecte imbricate până la un nivel oarecare.
Obiectul mai conține elemente de cod ce operează asupra acestuia și care se numesc metode. Obiectele ce conțin același tip de valori și aceleași metode sunt grupate în clase. O clasă poate fi interpretată ca fiind definiția de tip a obiectului respectiv.
Singura modalitate prin care un obiect poate accesa datele altui obiect este prin invocarea metodelor acelui obiect, ceea ce este cunoscut sub numele de trimitere de mesaje către obiectul respectiv.
Părțile interne ale obiectului respectiv, variabilele și metodele, nu sunt vizibile în exterior, obținându-se astfel două nivele de abstractizare a datelor. Spre deosebire de entitățile din modelul entitate-relație, fiecare obiect are un identificator unic indiferent de valorile pe care le conține.
Două obiecte ce au aceleași valori sunt distincte (polimorfism). Distincția se menține și la nivelul fizic prin atribuirea unui identificator unic al obiectului respectiv.
Modelul orientat pe obiecte are toate caracteristicile limbajului de programare orientat pe obiecte, făcând ca modelul relațional să fie coborât la stadiul de depozit de date.
Esențial pentru un astfel de model este faptul că proiectantul bazei de date poate opera cu fiecare element al bazei de date, inclusiv cu setul de operații ce manipulează datele din cadrul bazei de date în cadrul aplicației scrise într-un limbaj orientat pe obiecte.
De această dată însă nu mai există o separare clară între date și aplicație. Spre deosebire de modelul relațional, care are un suport teoretic extrem de solid, modelul orientat pe obiecte nu prezintă o astfel de caracteristică, ceea ce face să nu existe un consens în definirea lor. Totuși, organizația OMG (Object Management Group) a depus mari eforturi, reușind să propună un model ce a devenit standard pentru toate sistemele de gestiune a bazelor de date orientate pe obiecte.
Modelul obiectual-relațional
Acest model (cunoscut inițial sub numele de model de date relațional extins) a extins modelul relațional prin introducerea unor serii de elemente și caracteristici specifice modelului obiectual, cum ar fi: clase, încapsulare, moștenire. Cele mai cunoscute produse de pe piață sunt: Postgres, Informix, DB2, Oracle.
Scopul acestei extinderi a fost acela de a permite bazelor de date relaționale să opereze cu tipuri complexe de date, cum ar fi: imagini audio, video, elemente de proiectare. Modelul se află încă la stadiul incipient de dezvoltare, chiar dacă este promovat de cei mai mari producători de pe piață de produse de baze de date.
2.1.5. Modele fizice de date
Sunt modele utilizate la descrierea datelor la cel mai de jos nivel. Ele conțin informații despre structura înregistrărilor, ordinea înregistrărilor, precum și căile de acces la date. Din această categorie fac parte:
modelul unificat al datelor;
memoria cadru.
2.1.6. Avantajele bazelor de date relaționale
Sunt următoarele:
Integritate încorporată la mai multe nivele. Integritatea datelor este integrată în cadrul modelului la nivel de câmp pentru a asigura precizia datelor. La nivel de tabel asigură faptul că o înregistrare nu mai poate fi introdusă încă o dată în baza de date, precum și detectarea lipsei valorilor din câmpurile cheie primară. La nivel de relație asigură validitatea acestora între tabele. La nivel logic, asigură acuratețea logică a datelor.
Independența logică și fizică a datelor de programele aplicație: nici modificările efectuate de către utilizator modelului logic al bazei de date, nici modificările efectuate de către producătorul bazei de date implementării fizice a acesteia, nu vor afecta programele aplicațiilor care utilizează baza de date.
Garantează consistența și precizia datelor: datele sunt consistente și precise datorită multiplelor nivele de integritate ce pot fi introduse în baza de date.
Extragerea cu ușurință a datelor din baza de date. În urma comenzilor introduse de către utilizator, datele din baza de date pot fi extrase fie dintr-un singur tabel, fie dintr-o multitudine de tabele asociate prin intermediul relațiilor, ceea ce oferă posibilitatea prezentării datelor într-un număr nelimitat de moduri.
Acestea și alte avantaje au adus beneficii extrem de importante comunității de afaceri și tuturor acelora care au nevoie de colectarea și înmagazinarea de date. Deocamdată, bazele de date relaționale dețin supremația pe piața acestor produse, fiind alese în cele mai multe dintre cazuri.
Până de curând, cel mai mare dezavantaj al bazelor de date relaționale îl reprezenta faptul că programele aplicație care le foloseau erau foarte lente în execuție. Problema nu era una a bazelor de date relaționale, ci tehnologiei deficitare de care se dispunea la momentul introducerii modelului. Începând cu anii ’90 pașii înainte făcuți atât în domeniul hardware cât și software au făcut ca o astfel de problemă să fie din ce în ce mai puțin vizibilă.
2.1.7. Chei
O cheie este un câmp ce are o valoare unică, corespunzătoare fiecărei înregistrări dintr-un tabel. Sunt mai multe tipuri de chei, fiecare având propriile caracteristici.
2.1.7.1. Cheia candidat
Este un atribut sau un set de atribute ce identifică în mod unic un tuplu dintr-un tabel.
2.1.7.2. Cheia primară
Reprezintă una dintre cheile candidat desemnate în cadrul unui tabel. Orice tabel trebuie să aiba o cheie primară.
O cheie primară trebuie să fie:
Stabilă. Valoarea unei chei primare nu trebuie să se modifice sau să devină nulă pe tot parcursul existenței unei entități (Brooks, 1992). O cheie primară stabilă ajută la păstrarea unui model stabil (Whitener, 1989). De exemplu, dacă se analizează înregistrarea datelor unui student, valoarea cheii primare nu trebuie să se modifice în timp, așa cum se întâmplă cu valorile din câmpul în care se păstrează vârsta acestuia.
Minimală. Cheia primară trebuie să fie alcătuită dintr-un număr minim de câmpuri ce sunt capabile să asigure unicitatea.
Centrată pe date, nu pe informații. Nu trebuie să apară grupări de caracteristici în cadrul unei valori a unei chei ce păstrează meta-informații adiționale, deoarece nu se respectă principiul atomicității atributelor, crescând astfel posibilitatea ca valorile cheii primare să se modifice.
Definitivă. În momentul introducerii unei noi înregistrări, trebuie să existe posibilitatea introducerii unei valori. Cheia primară acționează ca un mecanism de constrângere suplimentară a entității deoarece nu poate fi introdusă o instanță a unui tip de entitate dacă aceasta nu are o valoare permisă în cheia primară.
Accesibilă. Oricine dorește să creeze, citească, sau șteargă o înregistrare trebuie să poată vizualiza valoarea cheii primare (Whitener, 1989).
2.1.7.3. Cheie alternativă
Este o cheie candidat ce nu a fost desemnată drept cheie primară. Ea poate deveni cheie primară dacă cheia primară aleasă inițial nu mai corespunde la un moment dat.
2.1.7.4. Cheie externă
Există doar în situația în care se stabilesc două sau mai multe relații între tabelele bazei de date. Un atribut al unui tabel trebuie să existe și în celălalt tabel legat de primul printr-o relație.
2.2. Modele arhitecturale: mainframe, integrate, file-server, client-server, distribuite
2.2.1. Introducere
De mult timp se cocheta cu ideea creării unei baze de date universale, adică o bază de date care să conțină informații din cît mai multe domenii și care să poată fi accesată de un număr cât mai mare de persoane. Până cu puțin timp în urmă acest ideal se menținea în domeniul viselor. Odată cu apariția a ceea ce numim astăzi World Wide Web un astfel de vis a devenit realitate.
Încă din cele mai vechi timpuri oamenii au avut nevoie de informații. O dată cu informația a apărut și necesitatea schimbului de informații. Pentru aceasta era nevoie de un suport material care să stocheze informația și să o transmită mai departe. S-a început cu cioplirea informațiilor în piatră și s-a continuat cu alte și alte soluții până în zilele noastre, când asistăm la decăderea unui suport (hârtia) și ridicarea altuia (suportul electromagnetic).
Odată cu evoluția omenirii, informația a crescut ca dimensiune, punându-se, prin urmare, problema stocării unei mari cantități de date. De asemenea, o altă problemă este regăsirea informației și, odată cu aceasta, rapiditatea obținerii rezultatului. Încă din zorii civilizației IT s-a observat că – pe lângă calculele ce erau preponderente în tehnologia informatică embrionară – computerele s-ar preta și la înmagazinarea și exploatarea volumelor mari de informații. Astfel, începând cu anul 1948 s-au făcut mai multe studii, cercetări și experimente privind stocarea datelor, iar de-a lungul timpului s-au manifestat mai multe modele, arhitecturi și tehnologii privind bazele de date. Acceptând un punct de vedere oarecum teoretic, fără însă a intra in detalii aride, vom trece in revistă principalele modele de concepție și organizare a bazelor de date, după care ne vom ocupa de arhitecturile de implementare a sistemelor de gestiune a bazelor de date (SGBD).
2.2.2. Istoric
Până spre anii ‘80 contau doar mainframe-urile, minisistemele și supercomputerele, bazele de date fiind foarte mari (răspunzând unor cerințe dure impuse de beneficiari pretențioși, pentru că doar aceștia aveau puterea financiară de a achiziționa tehnica motivat de probleme complexe și critice – este ușor să ne imaginăm baze de date referindu-se la sute de mii sau milioane de entități). Tendințele forțau mereu limite, iar de aici derivau problematici provocatoare privind performanța, accesibilitatea și mentenabilitatea. Prin anii ‘70, modelul relațional s-a cristalizat ca soluție viabilă, iar lupta concurențială dintre marii jucători de pe piața bazelor de date se va da până in vremea noastră pe arena SGBDR și SQL.
Mult timp modelul de organizare centralizat (datele sunt depozitate pe un sistem central de unde utilizatorii le accesează) a raspuns cel mai bine cerințelor de exploatare a bazelor de date. Și astăzi pentru aproape orice mediu departamental (sau grup de lucru) organizarea centralizată a informațiilor – și nu ne referim neapărat la baze de date (de exemplu, sistemele de gestiune și control al circulației documentelor – unde documentele pot fi orice: documentații, proiecte, desene CAD, arhive etc.) – constituie o primă opțiune.
Odată cu răspândirea și dezvoltarea calculatoarelor s-au deschis și orizonturile, iar ca o prima tendință s-a dovedit necesitatea descentralizării și interoperării. Proliferarea diverselor platforme (hardware și/sau sisteme de operare) au forțat definirea de standarde de schimb de date și de comunicații, precum și dezvoltarea rețelelor eterogene.
Iar pentru că lucrurile se întâmplau odată cu afluxul calculatoarelor personale, inevitabil programatorii s-au gândit la ceva intre SGBD și spreadsheet, iar de aici la apariția unor baze de date desktop de genul lui dBASE n-a fost decât pasul materializării.
Evoluția ramurii desktop a bazelor de date s-a făcut in paralel cu mainstream-ul, dar influențându-se reciproc. Cele mai evidente tendințe se pot descrie pe scurt astfel: bazele de date mici doreau să-și dezvolte funcționalități de sistem relațional (să poată defini relații și să încorporeze SQL) și să-și extindă limitele, iar cele mari și-au aplecat atenția asupra accesibilității, materializată prin interfețe utilizator facile chiar și pentru activitățile administrative (o interfață de calitate ajunge deseori un argument de piață).
2.2.3. Modelul mainframe
Modelul centralizat inițial presupunea că baza de date este organizată și stocată integral pe un sistem performant (denumit mainframe, sistem sau minisistem în funcție de criterii hardware) de unde poate fi accesată de mai multe console utilizator (terminale de acces cu putere de calcul redusă conectate la calculatorul central) prin intermediul unor aplicații de exploatare rezidente tot pe mainframe.
Modelul s-a dovedit performant și sigur atât în implementare, cât și în utilizare, dar au existat și câteva puncte sensibile. Problema delicată la mainframe-uri nu este numărul de utilizatori suportați (cum am fi tentați să credem), ci faptul că aplicațiile au o infrastructură rigida, a căror extindere determină implicații dure de organizare și administrare, pe lângă creșterile nedorite ale traficului de date prin rețea.
Extincția dinozaurilor n-a fost deloc completă: mulți încă mai fac față aplicațiilor critice (care nici nu pot fi întrerupte fără pierderi), iar interoperabilitatea cu arhitecturile moderne nu-i incomodează deloc, ba parca-și retrăiesc o a doua tinerețe…
2.2.4. Modelul integrat
Un mediu software independent, instalat pe un singur calculator, include atât baza de date propriu-zisă, cât și interfața de acces la date (un prim exemplu de astfel de mediu integrat este dBASE), astfel că singurul utilizator va fi beneficiarul. Accesarea datelor se face fie printr-un limbaj de generația IV (4GL) sau printr-un macrolimbaj, fie prin elemente de interfață (comenzi la prompter, dialoguri QBE, comenzi menu). Datele fiind organizate tabelar, exista posibilitatea de a proiecta aplicații relaționale.
Uzual, astfel de medii îngăduie dezvoltarea de aplicații nerelaționale, ceea ce se mai numește și organizare plată sau bidimensională, spre deosebire de organizarea relațională, care este multidimensională (atenție, există pericolul confuziei cu denumirea de „baza de date multidimensională“ care corespunde uzual domeniului date warehouse sau aplicațiilor DSS – decision support system – și OLAP – On-Line Analytical Processing, deservind analize economice necesare deciziilor manageriale, adică extragerii ad-hoc de informații sintetice, unde dimensionalitatea are un caracter mai abstract și mai dinamic și nu contravine modului de stocare).
Într-un sistem nerelațional (revenind la mediul independent), datele care altfel s-ar preta organizării în nomenclatoare (tabele cu înregistrări unice, legate de celelalte tabele prin relații unu-la-n) cunosc un grad excesiv de redundanță, iar actualizarea lor presupune un efort considerabil. (Redundanța datelor, adică faptul că baza de date conține aceleași date stocate de mai multe ori, ridică atât problema spațiului ocupat, cât mai ales dificultatea asigurării consistenței si actualității).
2.2.4.3. Modelul File-server
În sistemele de gestiune a bazelor de date folosite astăzi, se întâlnesc două concepte ce definesc modul de acces al clienților la o bază de date centralizată. Primul este conceptul “file-server” în care serverul lucrează numai cu fișierele de date, fiind impropriu ca aplicația să ceară un transfer de date. Cel de-al doilea concept este modelul “client-server”, în care serverul “înțelege” natura datelor cerute, fiind pregătit să execute astfel de cereri.
Soluția oferită de modelul “file-server” implică utilizarea unui server de fișiere centralizat aflat undeva pe o rețea, care pune la dispoziția clientului unități de disc logic cu fișiere partajate. Serverul de fișiere nu are cunoștințe despre cererile logice care se prelucrează, dar acționează sub forma unui disc ce poate fi accesat prin intermediul unei rețele pentru a transfera date de la/spre client. Toate aplicațiile rulează la client. Exemple de astfel de produse sunt FoxPro, dBase, MS Access. O bază de date de acest tip are o fiabilitate foarte scăzută deoarece ea se păstrează sub forma unui fișier într-un sistem de fișiere, fiind ușor de distrus dacă se produce o eroare în timpul unei prelucrări sau a unei pierderi de conexiune în timpul efectuării unei tranzacții.
2.2.4.4. Modelul Client-server
În modelul “client-server” avem de a face cu o bază de date centralizată care prelucrează cererile logice provenite de la client.
Un astfel de server “înțelege” atât natura cererii cât și structura și localizarea datelor, majoritatea calculelor fiind efectuate de motorul bazei de date.
Clientul are doar o interfață grafică cu care poate accesa baza de date de pe server, folosind aplicații pentru a transmite comenzi SQL serverului bazei de date, rezultatele fiind primite sub formă de tabele. Exemple de astfel de produse sunt: ORACLE, SQL Server, DB2, Sybase și Informix. Prin ținerea sub control, de către un server, a tuturor fișierelor bazelor de date, arhitectura “client-server” oferă o fiabilitate ridicată și o serie de alte caracteristici avantajoase ce nu pot fi oferite de arhitectura “file-server”, cum ar fi:
Copie de siguranță ce poate fi creată în timpul lucrului prin utilizarea unui planificator automat ce face copii ale bazelor de date fără a fi necesară întreruperea conexiunii cu utilizatorii.
Tranzacții sigure prin jurnalizarea tranzacțiilor, astfel încât actualizările efectuate prin intermediul unei tranzacții pot fi în orice moment refăcute sau anulate, ajungându-se astfel la ultima stare consistentă anterioară începerii tranzacției respective, indiferent dacă eroarea se produce la client sau la server. Deși motorul Microsoft Jet și fișierele .mdb oferă posibilitatea efectuării de tranzacții, acestea nu sunt gestionate prin intermediul unui jurnal separat, iar datele pot fi distruse fără a mai fi posibilă refacerea lor.
Fiabilitate și protecție sporită a datelor. O bază de date în model “file-server” poate fi reparată, în cazul apariției unei erori, dar în acest caz utilizatorul trebuie deconectat, lucru care se întâmplă foarte rar în cazul modelului “client-server”.
Procesarea mai rapidă a interogărilor. Dacă se folosește un fișier .mdb prin intermediul unei rețele, trebuie încărcat motorul Jet al bazei de date la clientul la care se face cererea de prelucrare. În acest fel traficul pe rețea este foarte mare, fiind necesar transportul unei mari cantități de date, mai ales atunci când baza de date este foarte mare. În cazul modelului “client-server”, prelucrările se efectuează direct pe server, care de obicei, este mult mai performant decât mașina clientului. Prelucrarea pe server duce la o încărcare mult mai mare a acestuia decât în cazul modelului “file-server”, dar traficul pe rețea va fi substanțial scăzut. Prezentând un exemplu cu 5 utilizatori, se constată faptul că în situația modelului “file-server” este posibilă blocarea rețelei, deoarece toate bazele de date trebuie aduse pe calculatorul local. Din acest motiv, atunci când utilizatorii pun întrebări complexe serverului se poate ca rețeaua să nu mai facă față solicitărilor.
În concluzie, soluțiile “file-server” nu sunt recomandate întreprinderilor de mari dimensiuni sau aplicațiilor extinse, preferându-se în acest caz soluția “client-server” care scade traficul de pe rețea și asigură o fiabilitatea mult crescută a sistemelor.
În același timp, suntem ispitiți să credem, ca un reflex al superficialității (acesta fiind unul dintre marile riscuri actuale ale informatizării), că dacă se implementează o baza de date ce depășește – să zicem – un milion de înregistrări, baza de date desktop (mediu integrat) nu mai face față și trebuie să ne orientam către un alt tip de SGBDR. Pentru operarea în regim monoutilizator lucrurile nu se prezintă chiar așa: performanțele (viteze de accesare și procesare a datelor) sunt cât se poate de comparabile dacă este vorba de un hardware bine echilibrat (un PC care să suporte fără probleme un SGBDR mare va favoriza și baza de date integrată). În acest caz altele sunt criteriile care ne orientează catre SGBDR-uri mari organizate in model client/server:
– operarea multiuser concurențială (considerat punctual, nici aici avantajele nu sunt nete deoarece un FoxPro/LAN cu file-server face față onorabil);
– descongestionarea traficului prin rețea datorită transmiterii doar a datelor țintă (adică un minim);
– controlul drepturilor utilizatorilor și monitorizarea activității (conectare și aplicații);
– implementări unice de logică centralizată (reguli, proceduri, declanșatoare – existente doar la nivelul serverului);
– gestionarea tranzacțiilor, aspect care devine capital/critic atunci când se administrează un sistem complex de date distribuite sau un mediu OLTP (on-line transactions processing); ceva mai recent – sub influența Internetului – tranzacțiile au loc prin comunicație asincronă (conversaționala) sau chiar fără confirmare ("fire-and-forget“);
– serverul asigura integritatea, consistența și actualitatea datelor (propagări de actualizări prin mecanismele de integritate referențială);
– optimizarea organizării fizice a datelor (colaborarea la un nivel cât mai jos cu sistemul de operare și cu sistemul de fișiere) și optimizarea accesului la date. (Un exemplu de colaborare la nivel fizic este posibilitatea SGBD-urilor de a face duplicări ale datelor – copiile de siguranță fiind unul dintre primele niveluri ale toleranței la defectări. Desigur ca și un LAN desktop – Novell, Windows NT – poate face mirroring, insă nuanțele diferă.)
– recuperarea datelor în caz de blocare/cădere a sistemului și refacerea tranzacțiilor neterminate;
– jurnalizarea acceselor, tranzacțiilor și a sesiunilor de lucru sau de administrare;
– economicitatea upgrade-ului: ridicarea performanțelor globale rezidă în principal în creșterea puterii calculatorului pe care rulează serverul bazei de date, privind mai puțin calculatoarele client pe care se afla software-ul front-end etc.
Client si server pot fi văzute și ca două procesoare distincte rulând pe mașini diferite (mai rar pe aceeași mașină), bazate eventual (dar nu obligatoriu) pe același sistem de operare. Comunicația prin care partea "client“ a aplicației solicită servicii părții „server“ se face prin mesaje (message-passing), fiind complet transparentă utilizatorului. Posturile de lucru pot fi uzual PC-uri, laptop-uri, stații UNIX sau Macintosh, iar serverul poate fi un mainframe, un server departamental sau chiar un PC bine dopat. Software-ul bazelor de date implementate prin arhitectura client/server se prezintă generic astfel: SGBD-urile asigură partea de server, iar aplicațiile de exploatare a datelor se află uzual la nivelul client (sculele de editare a aplicațiilor utilizator aparțin de producătorii SGBD-urilor implementate sau pot fi din familia celor bazate pe specificații deschise: ODBC, JDBC, Embeded SQL, DCOM, OLE etc.).
Repartizarea datelor și a aplicației (logicii) între straturile "client“ și "server“ nu este preimpusa, fiecare implementare fiind susceptibila de un optim.
Arhitectura client/server dovedește suplețe (modularitatea și scalabilitatea oferind disponibilitate crescută la reorganizări și extinderi) și deschidere (chiar se consideră ca ea a apărut din necesitatea de a asigura o deschidere și interoperabilitate superioare modelului centralizat cu mainframe).
Modelul client/server a fost și el susceptibil de perfecționări de principiu, iar una dintre cele mai interesante este impunerea de niveluri/straturi intermediare intre client și server (n-tier), ca raspuns la dilema legata de poziționarea programelor de aplicație (logica de operare/afacere): care dintre părți trebuie sa fie mai "groase“, clientul sau serverul? Întrucât avantajele locale erau permanent necomplementare, s-a dezvoltat ideea unui strat intermediar, concretizat într-un server de aplicații interpus între clientul subțire și serverul bazei de date (middle-tier), ambele capete fiind astfel descongestionate de partea de logica. Interesantă este și observația unor analiști care asociau tendința modernă de accentuare a clientului subțire cu revenirea la modelul mainframe cu terminale "chioare“. Oricum, cerințele actuale privind deschiderea mediilor informaționale determină diluarea graniței dintre modele, rețelele eterogene fiind văzute ca soluția cea mai viabilă de a menține echilibrul între permanentele inovații și conservarea investițiilor anterioare.
Însă cele mai deranjante dezavantaje ale arhitecturii client/server derivă din complexitatea ei (cerințe asupra personalului implicat: înțelegerea conceptuală a arhitecturii de către persoanele de decizie, precum și cunoștințe aprofundate pentru cei care implementează/dezvoltă efectiv sistemul/aplicațiile) și din standardizarea insuficientă.
Majoritatea serviciilor Internetului se desfășoară în regim client/server (banala navigare înseamnă un utilizator accesând datele dintr-un site-server prin intermediul unei aplicații client, care este browserul de Web), astfel că devine naturală implicarea SGBDR-urilor în aplicații Internet (de genul e-business sau e-commerce). Să ne imaginăm următorul scenariu: un furnizor de produse își organizează un catalog de produse (magazin virtual) pe care utilizatorii îl pot consulta prin navigatorul de acasă. Lucrurile se desfășoară prin pagina HTML pe care serverul de Internet o trimite clientului, la rândul ei respectiva pagina acționând ca șablon (formular/formă) de accesare a informațiilor comerciale din baza de date deservită de un server legat la site-server (cel mai frecvent baza de date conține și imagini dacă nu chiar și alte date multimedia). Iar daca utilizatorul va comanda din produsele expuse completând un formular din pagina Web (controlat printr-un script), se declanșează o altă serie de comunicații între client și server.
2.2.6. Baze de date distribuite
Adevăratul sens al atributului "distribuit“ în contextul SGBD-urilor corespunde nu faptului că sistemul permite accesarea datelor de la distanță (prin rețea), ci acelor implementări care îngăduie aplicațiilor și utilizatorilor să trateze baza de date ca pe un singur depozit logic chiar dacă datele constituente sunt repartizate în mai multe locații ale rețelei (transparența completă a localizării datelor). Totuși problema este delicată și pentru că – din punctul de vedere al analizei – se poate oricând crea o aplicație care să trateze unitar tabele de date situate pe calculatoare diferite. Dar pentru că adevărata bază de date se dorește independentă de limbaje (sau de mediile de dezvoltare) sunt de apreciat acele SGBD-uri care conțin integrate funcționalități care să asigure distribuirea datelor în nodurile rețelei.
Ținând cont că de obicei volumul și complexitatea datelor spulberă idealul "un computer foarte performant cumulând întreaga baza de date și deservind toți utilizatorii întreprinderii/organizației“ și trebuie găsită o soluție de compromis, devine foarte interesantă colecția de criterii practice de distribuire a datelor în cazul fiecărei implementări, particularitățile cerând un optim jalonat de următoarele aspecte:
– nu trebuie niciodată pierdut din vedere dezideratul vitezei;
– limita de stocare și puterea calculatoarelor gazda;
– limita de transfer a rețelei;
– preferabil ca fiecare aplicație să acceseze uzual un singur depozit al bazei de date (fără a împiedica accesarea cu frecvență redusa a celorlalte noduri ale rețelei);
– folosirea funcțiilor two-phase-commit existente pentru a asigura integritatea datelor actualizate distribuit;
– planificarea, controlul și minimizarea duplicării de obiecte ale bazei de date;
– corelarea organizării cu facilitățile de optimizare distribuită ale SGBD-ului.
Cercetatorul Chris Date (coleg de proiecte cu E.F. Codd) a enunțat cele 12 cerințe ideale cărora trebuie să li se supună bazele de date distribuite; dintre acestea 9 sunt următoarele:
Autonomia locală: datele locale sunt deținute și administrate local – nici un post nu depinde de altele pentru a funcționa.
Toate posturile sunt egale: nici un post nu se bazează pe o stație centrală.
Funcționare neîntreruptă: nu trebuie să fie necesară o oprire planificată (instalările/ștergerile efectuate la un post nu afectează funcționarea celorlalte).
Transparența amplasării: utilizatorii nu sunt obligați să știe unde sunt amplasate datele pentru a le extrage. Transparența fragmentării: relațiile dintre componentele bazei de date pot fi fragmentate pentru stocare, dar acest lucru rămâne transparent pentru utilizator.
Transparența duplicării: relațiile și fragmentele pot fi reprezentate fizic prin copii multiple stocate separat, dar transparent pentru utilizator.
Prelucrarea interogărilor distribuite: operațiile de citire/scriere se pot desfășura la mai multe posturi, permițând optimizarea locala și globală a interogărilor.
Actualizările distribuite: tranzacțiile singulare pot executa codul la mai multe posturi.
Independența de hardware: toate calculatoarele participă ca membri egali.
Independența de sistemul de operare: sunt suportate mai multe sisteme de operare conectabile la rețea. Independența de rețea: sunt suportate mai multe rețele prin protocoale comune.
Independența de bazele de date: se asigură accesul uniform (interfațare unică) pentru datele provenind din SGBD-uri diferite.
3.1. Bazele modelului relațional
Conceptul de bază de date introduce termenul de abstractizare a datelor prin mascarea față de utilizator a detaliilor legate de tehnica de stocare a datelor în calculator. Principalul instrument folosit la realizarea acestui scop este modelul de date, care este alcătuit dintr-un set de concepte ce pot fi utilizate la descrierea structurii bazei de date, cum ar fi de exemplu, tipurile de date, relațiile și constrângerile stabilite pentru datele reprezentate.
Există trei tipuri de modele de date: modelul de date conceptual, modelul de date logic și modelul de date fizic.
3.1.1. Modelul conceptual
Folosește o serie de concepte, cum ar fi entitate, relație și atribut pentru a descrie cât mai fidel modul în care este percepută de către utilizator realitatea ce urmează a fi reprezentată în cadrul unei baze de date. Pentru a realiza un model conceptual cât mai corect se folosesc o serie de instrumente ce ajută în modelare, dintre care cel mai folosit este diagrama entitate-relație. De obicei, proiectarea unui model conceptual respectă următorul algoritm:
Pasul 1. Identificarea tipurilor de entități. Constă din identificarea și documentarea principalelor tipuri de entități din punct de vedere al beneficiarului bazei de date. În acest scop este necesară citirea cu atenție a tuturor specificațiilor și cerințelor acestuia, urmată de crearea unei liste a potențialelor tipuri de entități. Tipurile de entități reprezintă obiectele sau conceptele ce prezintă cel mai mare interes în cadrul sistemului. De obicei, se creează mai multe tipuri de entități decât este necesar, urmând ca ulterior să se recurgă la o rafinare a acestora, eliminându-se unele dintre ele.
Pasul 2. Eliminarea tipurilor de entități duplicat. În primul rând trebuie să se obțină asigurarea că, într-adevăr, fiecare tip de entitate utilizat reprezintă un tip distinct de entitate și nu nume diferite ale aceluiași tip de entitate. Este foarte important să nu se cadă în capcana definirii unui tip de entitate care să reprezinte întregul sistem. De exemplu, la modelarea unei biblioteci, tipurile de entități pot fi cărțile, autorii, cititorii etc., dar în nici un caz nu poate fi definit un tip de entitate biblioteca deoarece aceasta reprezintă întregul sistem.
Pasul 3. Identificarea tipurilor de relații. În cadrul acestei etape se recurge la identificarea și documentarea celor mai importante tipuri de relații ce se pot stabili între tipurile de entități rămase după parcurgerea pasului anterior. În acest scop se examinează fiecare tip de entitate în parte pentru a putea determina poziția și legăturile acesteia în cadrul sistemului. În același timp se face o analiză a cardinalității și a participării fiecărui tip de entitate, identificându-se totodată constrângerile impuse tipurilor de entități participante.
Pasul 4. Identificarea și asocierea atributelor corespunzătoare fiecărui tip de entitate sau relație. În această etapă trebuie obținută asigurarea că tipurile de entități sunt cu adevărat necesare și nu sunt atribute ale altor tipuri de entități. De exemplu, telefonul poate fi o entitate de sine stătătoare sau un atribut exprimat sub forma unui număr de telefon atribuit tipului de entitate Studenți.
Pasul 5. Stabilirea domeniilor de valori ale atributelor. Se realizează printr-o analiză amănunțită a situațiilor ce pot apare, documentându-se fiecare hotărâre luată.
Pasul 6. Stabilirea atributelor cheie candidat și primară. Dacă în cadrul analizei se identifică mai multe chei candidat, se stabilește cheia primară, documentându-se hotărârea luată.
Pasul 7. Specializare/generalizarea tipurilor de entități. Aceasta etapă este una opțională în cadrul modelului relațional și are ca efect stabilirea superclaselor, respectiv a subclaselor tipurilor de entități, dacă este cazul.
Pasul 8. Construirea diagramelor entitate-relație. Prin parcurgerea acestei etape se asigură o mai bună înțelegere a realității care se modelează.
Pasul 9. Eliminarea tipurilor de relații duplicat.
Pasul 10. Revizuirea diagramei entitate-relație împreună cu beneficiarul bazei de date.
Modelarea realizată cu ajutorul unei diagrame entitate-relație este un proces iterativ. De obicei, nu există o singură soluție și, ca urmare, nici o singură diagramă de acest fel. Din acest motiv se practică crearea mai multor diagrame entitate-relație urmată de rafinarea fiecărei variante din care se va alege ulterior, împreună cu beneficiarul bazei de date, diagrama optimă. De remarcat este faptul că, de cele mai multe ori, nu se poate spune că o variantă este mai bună decât alta, dar unele variante pot oferi soluții mai bune decât altele.
Implementarea tipurilor de relații în cadrul tabelelor
Dându-se o relație R care se stabilește între două tipuri de entități E și F se impun următoarele reguli:
dacă relația E-R-F este de tip unu-la-mulți, cheia primară a relației F se introduce în relația E;
dacă relația E-R-F este de tip unu-la-unu, cheia primară a relației E se introduce în relația F, sau cheia primară a relației F se introduce în relația E;
dacă relația E-R-F este de tip mulți-la-mulți, se creează o nouă relație ce conține cheile primare atât ale lui E cât și ale lui F;
dacă relația R are atribute, acestea trebuie transferate în cadrul unei relații folosindu-se cheile externe.
3.1.2. Modelul logic
Acest model folosește concepte ce mai pot fi înțelese încă de către utilizator, dar care presupun reprezentări referitoare la modul în care utilizatorul dorește să vizualizeze datele. În continuare tehnicile de înmagazinare a datelor rămân transparente utilizatorului. Proiectul logic al unei baze de date relaționale creează și validează modelul logic de date local. Scopul urmărit este acela de a construi un model logic de date bazat pe modelul conceptual de date creat anterior, după care se trece la validarea acestui model cu ajutorul tehnicii normalizării. Un astfel de model parcurge, de regulă, următorul algoritm:
Pasul 1. Transformarea modelului conceptual local în model logic local de date. În acest scop se trece la rafinarea modelului conceptual de date local, prin eliminarea caracteristicilor incomode:
eliminarea relațiilor mulți-la-mulți;
eliminarea relațiilor complexe;
eliminarea relațiilor recursive;
eliminarea relațiilor ce conțin atribute;
revizuirea relațiilor unu-la-unu.
Pasul 2. Stabilirea relațiilor corespunzătoare modelului logic de date. În această etapă se creează și documentează fiecare relație, inclusiv cheile primare și externe.
Pasul 3. Validarea modelului folosind tehnica normalizării.
Pasul 4. Validarea modelului în cazul folosirii tranzacțiilor. Trebuie să se obțină asigurarea că modelul de date creat suportă tranzacțiile cerute de către beneficiarul bazei de date.
Pasul 5. Stabilirea constrângerilor de integritate. În acest scop trebuie identificate:
datele necesare;
integritatea referențială;
constrângerile de domeniu impuse atributelor;
constrângerile logice;
integritatea entității.
Pasul 6. Revizuirea modelului logic local împreună cu beneficiarul bazei de date.
Pasul 7. Construirea și validarea modelului logic global de date. Scopul acestei etape este acela de a realiza, pe baza modelelor logice locale de date un singur model logic global ce poate fi utilizat la reprezentarea realității care se modelează.
Pasul 9. Unificarea modelelor logice locale în cadrul unui singur model loc global. Se urmăresc:
revederea numelor tipurilor de entități și a cheilor primare;
revederea numelor relațiilor;
aducerea în cadrul unui singur model a tipurilor de entități din cadrul modelelor logice locale;
introducerea în cadrul modelului logic global a tipurilor de entități specifice fiecărei vederi logice locale;
aducerea în cadrul unui singur model a tipurilor de relații din cadrul modelelor logice locale;
căutarea tipurilor de entități și relații lipsă;
verificarea cheilor externe;
verificarea constrângerilor de integritate;
crearea modelului logic global de date;
actualizarea documentației.
Pasul 10. Validarea modelului logic global. Se face prin utilizarea normalizării.
Pasul 11. Prevederea modificărilor ce trebuie efectuate în vederea dezvoltărilor ulterioare.
Pasul 12. Revizuirea modelului logic global împreună cu beneficiarul bazei de date.
3.1.3. Modelul fizic
Acest tip de model descrie reprezentarea datelor în formatul, modul de acces și ordinea reală în care acestea sunt păstrate. Fiecare câmp dintr-un tabel are un anumit tip de dată. Standardul SQL-92 suportă o varietate foarte largă de tipuri de date dintre care enumerăm:
char(n) sau character(n): șir de caractere de lungime fixă, stabilită de utilizator;
varchar(n) sau character varying: șir de caractere de lungime variabilă a cărui lungime maximă este stabilită de către utilizator;
int sau integer: tipul întreg a cărui lungime depinde de sistem;
smallint: tip întreg de dimensiuni mai mici a cărui lungime depinde de sistem;
numeric(p, d): un număr zecimal a cărui precizie este stabilită de către utilizator, ce constă dintr-un număr total de cifre (p), dintre care d reprezintă cifrele de la partea zecimală; de exemplu, numeric(3, 1) permite stocarea numărului 1.22 exact așa cum apare și nu în formatul 1.2;
real sau double precision: numere reale a căror precizie depinde de sistem;
float(n): număr real a cărui precizie este stabilită de către utilizator (n cifre);
date: tip de dată calendaristică;
time: exprimă ora unei zile în ore, minute și secunde.
SQL-92 permite efectuarea de calcule aritmetice și de comparații pe diverse intervale numerice, folosind operatori de transformare a tipurilor (cast).
3.2. normalizarea bazelor de date. Forme normale
3.2.1. Normalizarea
Normalizarea reprezintă proiectul logic al unei baze de date. Principalul obiectiv al unui proiect logic este dezvoltarea schemelor relaționale corecte. În acest scop trebuie:
evitate datele redundante;
evitate anomaliile de modificare;
asigurată reprezentarea relațiilor dintre atribute;
facilitată verificarea actualizărilor care nu trebuie să forțeze integritatea bazei de date.
Normalizarea este un proces de reducere a redundanțelor și creștere a stabilității unei baze de date. Existența redundanțelor într-o bază de date produce următoarele efecte defavorabile:
pierdere inutilă de spațiu;
scăderea performanțelor de cost;
apariția inconsistențelor;
imposibilitatea reprezentării datelor.
Normalizarea presupune determinarea locului în care trebuie plasate anumite date în cadrul tabelelor bazei de date, stabilind totodată relațiile dintre acestea. Prin cuvântul “normă” se înțelege respectarea unui standard și reprezintă setul de condiții impuse și cunoscute sub denumirea de forme normale. Pentru a respecta aceste reguli trebuie identificate condițiile care trebuie respectate în scopul evitării încălcării integrității datelor impunându-se în acest scop descompunerea relațiilor. Denormalizarea este procesul invers, opus normalizării efectuat cu scopul îmbunătățirii performanțelor bazei de date.
Normalizarea este, cu alte cuvinte, un proces de descompunere a unui tabel în două sau mai multe tabele cu scopul eliminării redundanțelor care generează anomalii de actualizare. În timpul procesului de normalizare, structura tabelelor se testează cu ajutorul formelor normale care impun regulile de descompunere.
O formă normală reprezintă, cu alte cuvinte, un set specific de reguli ce pot fi utilizate în scopul testării structurii unui tabel pentru a obține asigurarea că structura respectivă nu pune probleme la introducerea sau extragerea datelor.
Formele normale folosite în mod curent sunt Prima, A doua, A treia formă normală, Forma normală Boyce-Codd, A patra și A cincea formă normală.
Descompuneri
Fie U o schemă de relație. Un set de scheme de relații {R1 , R2 , … , Rn} reprezintă o descompunere a lui U dacă și numai dacă:
U = R1 R2 …Rn
și dacă la reunire nu se pierde informație.
O descompunere {R, T} a lui U se face fără pierdere de informație (referitor la setul de constrângeri) dacă:
în cazul oricărei instanțe a R, T, și U. Altfel, descompunerea se spune a fi cu pierdere de informații. Un caz mai general este însă:
U R T
Deși descompunerea unui tabel în tabele mai mici este de dorit dintr-un anumit punct de vedere, în scopul reducerii redundanțelor și evitării anomaliilor, totuși o astfel de întreprindere implică anumite riscuri care, în principal, se manifestă sub două aspecte:
posibila pierdere de informație;
posibila pierdere a dependențelor.
Se prezintă în continuare un exemplu de pierdere de informație.
Descompunerea R = {A, B}
R1 = {A} R2 = {B}
A ( r) B ( r)
Proprietățile descompunerii
O schemă relațională R care are o mulțime de dependențe funcționale F se descompune în relațiile R1 și R2.
Lipsa pierderii de informație.
Se verifică dacă cel puțin una dintre următoarele dependențe se află în F+
R1R2 R1
R1R2 R2
Dacă nu, descompunerea se poate face cu pierdere.
Păstrarea dependențelor.
Fie Fi o mulțime de dependențe din F+ ce conține doar atributele relației Ri (cu notația: Fi = ).
Se verifică dacă (F1 F2)+= F+. Dacă se modifică o relație nu trebuie să se verifice dacă se păstrează dependențele în celelalte relații.
Eliminarea redundanțelor.
Dependențe funcționale
Dependențele funcționale sunt constrângeri aplicate mulțimii de relații din baza de date. Acestea permit exprimarea unor fapte din lumea reală. Noțiunea generalizează ideea de supercheie. K este o supercheie a relației R dacă în orice situație în care t1[K] = t2[K], t1[R] = t2[R].
Dependențele funcționale permit exprimarea constrângerilor ce nu pot fi exprimate prin intermediul supercheilor (cheia primară, cheia candidat). O mulțime F de dependențe funcționale poate fi folosită în două moduri:
pentru a specifica constrângerile aplicate relațiilor;
pentru a verifica dacă relațiile mai sunt valabile în cazul aplicării mulțimii de dependențe funcționale.
Un atribut A este dependent funcțional de o mulțime de atribute B dacă și numai dacă:
valoarea lui A este determinată numai prin intermediul valorilor lui B;
valorile lui B determină în mod unic o valoare a lui A
Dependența funcțională se reprezintă astfel:
B A
ceea ce înseamnă că o valoare a lui B afectează valoarea lui A. O valoare a lui A nu afectează o valoare a lui B. B reprezintă determinantul, A reprezintă dependentul/determinatul.
Dependențele funcționale sunt utilizate în scopul verificării corectitudinii unei relații.
Exemple:
K este o supercheie a relației R dacă K R astfel încât pentru orice t1[k] = t2[k], t1[R]= t2[R]. K determină funcțional toate atributele dintr-un tuplu al lui R.
Eliminarea redundanțelor (dependența parțială, dependența tranzitivă, dependența funcțională propriu-zisă, aserțiunile logice ce implică dependențe funcționale).
Verificarea constrângerilor aplicate pe un set de relații.
Verificarea corectitudinii modelului entitate-relație.
Verificarea reprezentărilor întâlnite în diagramele entitate-relație (atribute ale unor entități incorect alese, stabilirea de constrângeri de cardinalitate eronate, lipsa tipurilor de relație unu-la-mulți corespunzătoare tipului de entitate ales sau existența atributelor multivaloare).
Dându-se o relație R care are o mulțime de dependențe funcționale F, și o cheie K se impune identificarea atributelor independente:
Cheia trebuie să identifice toate atributele unei relații și dacă un atribut depinde doar de o parte a cheii, atunci se spune că el este parțial dependent de cheie.
Dacă un atribut depinde de o cheie în mod tranzitiv, atunci el depinde în mod direct de alt atribut și, ca urmare, este independent de cheie. Atributul este dependent tranzitiv față de cheie
Dependențele funcționale sunt transparente modelului entitate-relație.
Clasa dependențelor funcționale
Clasa reprezintă în matematică mulțimea elementelor distincte ale unei mulțimi.
Definiție: Fie F o mulțime de dependețe. Clasa dependențelor funcționale corespunzătoare mulțimii F (F+), este alcătuită din toate dependențele funcționale generate de dependențele mulțimii F.
Exemplu:
R = {A, B, C, D}
F= {A B, A C, CD A}
Elementele mulțimii F+ sunt: A BC
CD B
AD B
AD ABCD
Dacă R F+ atunci este o supercheie (cheie candidat, cheie primară) a lui R.
Axiomele lui Armstrong ajută la determinarea clasei dependențelor funcționale.
Reflexivitatea: Dacă atunci (oricare ar fi mulțimile de atribute și ).
Exemplu: {D} {D,C}, astfel încât DC D
Augmentarea: Dacă atunci .
Exemplu: dacă C D, atunci BC BD
Tranzitivitatea: Dacă și atunci .
Exemplu: dacă C D și DE, atunci C E.
Axiomele lui Armstrong sunt necesare și suficiente. Sunt necesare pentru că generează numai dependențe funcționale corecte și sunt suficiente deoarece generează toate dependențele funcționale posibile (F+) pe baza unei mulțimi date, F.
Mai există și alte proprietăți suplimentare:
Reuniunea: Dacă și atunci .
Exemplu: dacă C D și C B atunci C BD
Descompunerea: Dacă atunci și .
Exemplu: dacă C BD atunci C B și C D
Pseudotranzitivitatea: Dacă și atunci .
Exemplu: dacă C D și AD B atunci CA B
Aceste proprietăți sunt necesare.
Dependențe multivalorice
Următorul pas necesar este cel de determinare a tuturor dependențelor multivalorice care sunt generate în mod logic de o mulțime dată de dependențe multivalorice.
Fie R o schemă de relație și , . În relația R există o dependență multivalorică dacă în orice relație r( R), oricare ar fi perechile de tupluri t1 și t2 din r pentru t1[] = t2[], există tuplurile t3 și t4 în r astfel încât:
t1[] = t2[] = t3[] = t4[]
t3[] = t1[]
t3[ R -] = t2[ R – ]
t4[] = t2[]
t4[ R -] = t1[ R -]
Reprezentarea tabelară a dependenței multivalorice este:
Fie R o schemă de relație cu o mulțime de atribute ce se pot divide în trei submulțimi nevide, A, B, C. A B (A îl multidetermină pe B) dacă și numai dacă pentru toate relațiile posibile r( R)
{a1 , b1 , c1} r și {a1 , b2 , c2} r rezultă
{a1 , b1 , c2} r și {a1 , b2 , c1} r
Definiția de mai sus presupune formalizarea noțiunii prin care unei valori oarecare a lui A îi este asociată o mulțime de valori ale lui B și o mulțime de valori ale lui C, iar mulțimile B și C sunt independente una față de alta.
Dependențele multivalorice sunt utilizate în două moduri:
Pentru a verifica corectitudinea relațiilor în cazul apariției unei mulțimi de dependențe funcționale și multivaloare.
Pentru a specifica constrângerile aplicate mulțimii de relații.
Dacă o relație r nu satisface o dependență multivalorică, se poate crea o altă relație r’ care satisface dependența multivalorică prin adăugarea de tupluri relației r.
Aici se folosește același concept ca și în cazul dependențelor funcționale. Fie D o mulțime de dependențe funcționale și multivalorice. Mulțimea D+ a lui D reprezintă mulțimea tuturor dependențelor funcționale și multivalorice generate de D. Mulțimea D+ se poate calcula pe baza mulțimii D, cu ajutorul definițiilor formale ale dependențelor funcționale și multivalorice dar, pentru a determina mulțimea dependențelor, sunt mai ușor de folosit regulile de inferență.
Următoarea listă de reguli de inferență aplicate dependențelor funcționale și multivalorice este necesară și suficientă (primele trei reguli reprezintă axiomele lui Armstrong):
1. Reflexivitatea. Dacă α reprezintă mulțimea atributelor și βα, atunci α β.
2. Augmentarea. Dacă α β și γ nu este o mulțime de atribute, atunci γα γβ.
3. Tranzitivitatea. Dacă α β și β γ, atunci α γ.
4. Complementaritatea. Dacă α β, atunci α R – β – α.
5. Augmentarea multivalorică. Dacă α β, iar γR și δ γ, atunci γα δβ.
6. Tranzitivitatea multivalorică. Dacă α β și β γ, atunci α γ – β.
7. Duplicarea. Dacă α β, atunci α β.
8. Cuplarea. Dacă α β, iar γβ, există δ astfel încât δR, iar δβ = și δ γ, atunci α γ.
Păstrarea dependențelor
Problema păstrării dependențelor, atunci când vorbim despre dependențele multivalorice, nu este la fel de simplă ca în cazul dependențelor funcționale. O descompunere a schemei R în schemele R1,R2, . . .,Rn este o descompunere cu păstrarea dependențelor, corespunzătoare mulțimii D a dependențelor funcționale și multivalorice dacă, pentru fiecare mulțime de relații r1(R1), r2(R2), . . . , rn(Rn) oricare ar fi i, ri satisface Di (restricția mulțimii D pe Ri), există o relație r(R) care satisface mulțimea D și pentru care ri = ΠRi(r), oricare ar fi i.
Dacă se dă o mulțime de dependențe funcționale și multivalorice, proiectul bazei de date ar trebui să îndeplinească următoarele trei criterii:
1. Să fie adusă la forma normală 4.
2. Să păstreze dependențele.
3. Să nu piardă informație.
Dacă nu pot fi îndeplinite toate cele trei criterii, se poate ajunge la un compromis, cerându-se respectarea doar a primelor două criterii.
Dependențele de cuplare (joncțiune)
Proprietatea de lipsă a pierderilor datorate cuplărilor este una dintre proprietățile necesare obținerii unui proiect corespunzător al unei baze de date, datorită faptului că dacă această proprietate nu se respectă se pierde informație. După ce relațiile au fost testate în raport cu dependențele funcționale și multivalorice, este obligatoriu să se folosească aceste dependențe pentru a arăta că descompunerile nu au pierderi de informație datorate cuplărilor.
Fie R o schemă de relație și R1, R2, . . ., Rn o descompunere a lui R. Dependența de cuplare *(R1, R2, . . . , Rn) este folosită pentru a restrânge mulțimea relațiilor la acelea pentru care R1, R2, . . .,Rn nu reprezintă o descompunere cu pierdere de cuplare a lui R. Formal, dacă R = {R1, R2 . . . Rn}, se spune că o relație r(R) satisface dependența de cuplare *(R1, R2, . . .,Rn) dacă:
r =
O dependență de cuplare este trivială dacă una dintre relațiile Ri este chiar R. Fie dependența de cuplare *(R1, R2) pe schema R. O astfel de dependență impune ca pentru toate r(R),
r = ΠR1 (r) ΠR2 (r)
Fiecare dependență de cuplare de forma *(R1, R2) este, din acest motiv, echivalentă cu o dependență multivalorică. Există însă dependențe de cuplare care nu sunt echivalente cu nici o dependență multivalorică. Cel mai simplu exemplu de astfel de dependență îl reprezintă schema:
R = {A, B, C}
cu dependența de cuplare:
*((A, B), (B, C), (A, C))
care nu este echivalentă cu nici o mulțime de dependențe multivalorice.
Așa cum dependența multivalorică reprezintă o modalitate prin care se demonstrează independența unei perechi de relații, dependența de cuplare este o modalitate de a demonstra că elementele unei mulțimi de relații sunt independente unele față de altele. Noțiunea de independență a relațiilor este o consecință naturală a modului general de definire a unei relații.
În cazul dependențelor funcționale și multivalorice, este posibilă folosirea unui set de reguli necesare și suficiente. Din păcate un set de reguli asemănător nu există și în cazul dependențelor de cuplare.
3.2.2. Forme normale
Sunt proprietăți sau constrângeri aplicate unei scheme de relație cu scopul de a atinge anumite obiective, cum ar fi reducerea redundanțelor. Există 6 forme normale aplicate de obicei:
Prima formă normală (sau FN 1).
A doua formă normală (sau FN 2).
A treia formă normală (sau FN 3).
Forma normală Boyce Codd (sau FNBC).
A patra formă normală (sau FN 4).
A cincea formă normală (sau FN 5).
Fiecare dintre cele 6 forme normale este mai restrictivă ca predecesoarea sa. Astfel, de exemplu, o schemă de relație aflată în forma normală trei este și în forma normală doi, așa cum se reprezintă în figura de mai jos:
Figura 3.1. Forme normale
Scopul formelor normale este acela de a elimina redundanțele din cadrul relațiilor prin descompunerea acestora în două sau mai multe relații, fără însă a pierde informație, ceea ce înseamnă faptul că este posibilă, în orice moment, revenirea la relația originară doar pe baza relațiilor obținute din descompunere.
Prima formă normală (FN 1)
Scopul formei normale unu este acela de a simplifica structura unei relații prin obținerea asigurării că ea nu conține date care mai pot fi descompuse sau date generatoare de valori repetitive, ceea ce înseamnă faptul că nici un atribut nu poate avea o mulțime de valori. Prin acțiunea specifică de descompunere, atributele ce nu respectă aceste condiții sunt plasate în relații separate, păstrându-se atribute de legătură care au același tip de dată și aceeași dimensiune. Fiecare tabel are o cheie primară. De asemenea, o schemă relațională R se află în forma normală unu dacă și numai dacă fiecare atribut se află la nivel atomic.
A doua formă normală (FN 2)
O dependență funcțională X Y se spune că este o dependență funcțională completă dacă prin eliminarea unui atribut din X se pierde această dependența.
i
De exemplu, AB C este o dependență funcțională completă numai dacă C depinde funcțional atât de B cât și de A.
O schemă relațională se află în forma normală doi dacă și numai dacă fiecare atribut care nu face parte din cheie depinde funcțional de întreaga cheie. Cu alte cuvinte, o relație se află în forma normală doi dacă și numai dacă se află în forma normală unu și dacă depinde funcțional de întreaga cheie. Altfel relația trebuie descompusă.
A treia formă normală (FN 3)
O relație se află în forma normală trei dacă și numai dacă se află în forma normală doi și dacă fiecare atribut care nu face parte din cheie nu depinde tranzitiv de aceasta. Prin urmare, fiecare atribut care nu face parte din cheie nu poate depinde funcțional decât de aceasta. Pentru a ajunge din forma normală doi în forma normală trei este necesar să:
se determine dependențele funcționale dintre atribute;
se descompună relația în alte relații, fără a pierde însă informație.
Forma normală Boyce-Codd
O schemă de relație R se află în FNBC dacă, pentru toate dependențele funcționale ce au loc în R și sunt de forma X Y în care RX și RY sunt îndeplinite condițiile:
X Y este trivială.
X este o cheie candidat a schemei de relație R astfel încât X R.
Cu alte cuvinte, fiecare atribut trebuie să depindă de cheie, de întreaga cheie și de nimic altceva. FNBC este o generalizare a formelor normale doi și trei.
De remarcat este faptul că nu întotdeauna este posibilă descompunerea în FNBC cu păstrarea dependențelor.
Forma normală patru (FN 4)
Forma normală patru se bazează pe conceptul de dependență multivalorică. O dependență multivalorică apare doar în relațiile ce au cel puțin trei coloane. Dacă una dintre coloane are rânduri ale căror valori corespund unei singure valori ale unui rând dintr-o altă coloană, atunci se spune că a apărut o dependență multivalorică. O relație se află în forma normală patru dacă și numai dacă se află în forma normală Bozce-Codd și dacă nu are dependențe funcționale multivalorice.
A cincea formă normală (FN 5)
A cincea formă normală se bazează pe conceptul de dependență de cuplare. Dependența de cuplare este o proprietate ce garantează că nu se generează înregistrări false la reunirea relațiilor obținute prin descompunere.
O relație se află în forma normală cinci dacă ea nu poate fi descompusă în alte relații fără a pierde informație. Cu alte cuvinte, dacă se adaugă un rând suplimentar unei relații care nu se află în forma normală cinci și dacă această relație se descompune în alte relații, prin refacerea relației inițiale se obțin înregistrări false.
O dependență de cuplare (joncțiune) JD(R1, R2, … ,Rn) reprezintă o constrângere aplicată relației R, care arată faptul că fiecare instanță r(R) trebuie să aibe pierdere de informație prin descompunerea în relațiile R1, R2, … , Rn.
Ä
O dependență multivalorică reprezintă un caz special al unei dependențe de cuplare în care n = 2. Dependența de cuplare JD(R1, R2,…, Rn) este o dependență de cuplare trivială dacă unele relații Ri = R.
O schemă de relație R se află în forma normală cinci referitor la o mulțime F de dependențe funcționale, multivalorice, și de cuplare dacă pentru fiecare dependență de cuplare netrivială JD(R1, R2, … , Rn) din F, fiecare Ri este o supercheie a lui R.
Æ
3.3. Regulile lui Codd
Edgar F. Codd a murit în data de 18 aprilie 2003, la vârsta de 79 de ani. Codd a fost un cercetător, angajat al firmei IBM, care a dezvoltat pentru prima oară, în 1970, modelul relațional al bazelor de date în care prezintă operațiile ce pot fi efectuate asupra unei baze de date cu scopul obținerii accesului rapid și corect la acestea. Un model al unei baze de date are în vedere modul de stocare a datelor cât metodologia folosită la extragerea și actualizarea acestora. Pe parcursul anilor ‘60-’70 Codd a căutat să rezolve problemele induse de modelul ierarhic al bazelor de date care se folosea la IBM în acea perioadă. Rezultatul acestor cercetări s-a materializat în promovarea modelului relațional ca o soluție alternativă a modelului ierarhic care se bazează pe teoria matematică a mulțimilor.
Spre deosebire de sistemele ierarhice rigide, bazele de date relaționale sunt ușor de parcurs, manipulat și modificat. În principiu, acestea se bazează pe conceptul de tabel bidimensional (numit și relație), fiecare tabel fiind alcătuit din înregistrări (rânduri orizontale, numite și tupluri) și câmpuri (coloane verticale numite și atribute). În esență, o bază de date relațională este alcătuită dintr-o colecție de tabele bidimensionale în care coloanele unui tabel pot conține asocieri cu rândurile altor tabele în scopul corespondenței datelor.
La început IBM nu a luat în considerație ideile revoluționare ale angajatului său, datorită marilor investiții făcute în produsul de baze de date ierarhice, IMS, pe care încercau să-l promoveze masiv pe piață. Și astfel s-au scurs 7 ani de la lucrările lui Codd până când Larry Ellison ce conducea o companie ce ulterior avea să devină ORACLE a creat primul produs comercial de baze de date relaționale. În 1981 IBM a realizat produsul SQL/DS, primul lor produs relațional, urmat în 1983 de celebrul DB2.
În 1985 Codd a publicat o listă de reguli care definesc simplu și concis o bază de date relațională ideală, aceste reguli devenind standardul de evaluare a sistemelor relaționale, fiind în același timp și un ghid de proiectare a tuturor sistemelor de baze de date relaționale. După publicarea lucrării, Codd a afirmat că va fi foarte greu, dacă nu imposibil de creat un sistem care să satisfacă în totalitate setul de reguli, lucru care rămâne valabil și astăzi. La cele mai multe dintre sistemele relaționale de baze de date regulile 6, 9, 10, 11 și 12 sunt foarte greu de respectat. În continuare se va face o scurtă trecere în revistă a fiecăreia dintre cele 12 reguli.
3.3.1. Regula informației
Toate informațiile transferate în cadrul unei baze de date relaționale trebuie reprezentate în mod explicit la nivel logic într-o singură modalitate, sub formă de valori în cadrul unor tabele. Aceasta este, ceea ce se numește, reprezentare logică a datelor. Fiecare linie sau tuplu dintr-un tabel (relație) reprezintă intrări în coloane modelul aplicându-se la fel în întregul tabel astfel încât fiecare rând are același format.
Fiecare linie din cadrul tabelului este identificată prin intermediul valorii unei coloane sau combinații de coloane, numită cheia primară. Fiecare rând din cadrul tabelului poate fi accesat prin intermediul unei chei externe. Un sistem de gestiune a bazelor de date relaționale trebuie să manipuleze datele folosind doar instrumente specifice modelului relațional. Din acest motiv, atât datele cât și metadatele (datele despre date) trebuie păstrate în tabelele bazei de date.
3.3.2. Regula de garantare a accesului
Fiecare dată stocată într-o bază de date relațională trebuie să poată fi logic accesibilă utilizatorului prin apelarea numelui tabelului în care se află, prin valoarea cheii primare și prin numele unei coloane aparținătoare tabelului respectiv. Accesul la date trebuie să se facă simplu, fără a exista ambiguități în exprimare. Modelul relațional nu se preocupă de aspectele fizice ale extragerii datelor din tabele. Această regulă afirmă faptul că utilizatorul trebuie să aibe acces la datele stocate în baza de date doar prin intermediul numelor și valorilor. Cheia primară, prin care se identifică în mod unic o anumită înregistrare din cadrul unui tabel, reprezintă elementul fundamental al modelului relațional. într-un tabel nu poate exista decât o singură cheie primară care nu are voie să primească valori NULL.
3.3.3. Valorile NULL
Valorile NULL (diferite de șirul de lungime zero sau de numărul zero) sunt utilizate în cadrul sistemelor de gestiune a bazelor de date relaționale pentru a reprezenta informația lipsă sau indisponibilă la un moment dat, indiferent de tipul de dată și sunt obligatorii în orice sistem complet relațional. De asemenea, astfel de reprezentări trebuie să poată fi manipulate într-un mod sistematic și fără echivoc de către orice sistem de gestiune al bazelor de date relaționale (Date, 1991).
O valoare NULL poate apare oriunde în cadrul sistemului de gestiune al bazelor de date relațional, dar nu poate fi atribuită nici unei chei primare, majoritatea sistemelor admițând specificarea conceptului de câmp nenul sub forma unei constrângeri ce interzice folosirea valorilor NULL în câmpul respectiv (Parkhurst, 2002).
3.3.4. Catalog actualizat permanent pe baza modelului relațional
Descrierea bazei de date este reprezentată, la nivel logic, în același fel ca și datele obișnuite, astfel încât utilizatorii autorizați pot folosi același limbaj relațional pentru a pune întrebări referitoare la structura acesteia. Sistemul trebuie să suporte existența unui catalog relațional accesibil utilizatorilor autorizați prin intermediul aceluiași limbaj de interogare folosit și în cazul datelor obișnuite (Date, 1991).
O bază de date relațională trebuie să se autodescrie (Moore).
Catalogul reprezintă locul în care – alături de alte lucruri – se păstrează toate schemele (externe, conceptuale, interne), dar și toate corespondențele (externă/conceptuală, conceptuală/internă). Cu alte cuvinte, catalogul conține informații detaliate (numite și metadate) despre obiectele de interes ale bazei de date și ale întregului sistem (Date, 2000).
3.3.5. Regula de înțelegere a sublimbajului de manipulare a datelor
Un sistem relațional poate folosi mai multe limbaje sau moduri de folosire a terminalelor, dar acesta trebuie să suporte cel puțin un limbaj relațional care:
are sintaxă liniară;
poate fi folosit atât interactiv cât și din cadrul altor programe aplicație;
suportă:
operații de definire a datelor (inclusiv definirea și folosirea vederilor);
operații de manipulare a datelor (extrageri de date, dar și actualizări);
constrângeri de integritate și securitate;
operații de gestiune a tranzacțiilor (început, sfârșit, reluare).
(Date, 1991).
În realitate toate sistemele comerciale de gestiune a bazelor de date relaționale folosesc limbajul structurat de interogare (SQL).
3.3.6. Regula de actualizare a vederilor
Toate vederile care sunt teoretic actualizabile, pot fi actualizate de către sistem. Fiecare vedere trebuie să suporte același set de reguli de manipulare prin care se poate accesa în mod direct la fel ca și un tabel obișnuit (Parkhurst, 2002).
O vedere este un tabel virtual, care provine din cel puțin un tabel de bază și generează o serie de reprezentări ale datelor vizibile utilizatorilor. Tabelele de bază sunt tabelele reale ale bazei de date, cu reprezentare concretă în mediul de stocare. Deoarece vederile nu înmagazinează date ci interogări, acestea sunt numite tabele virtuale (Johnson, 1997).
Date a luat în discuție două principii importante ce trebuie avute în vedere la actualizarea unei vederi:
Principiul interschimbabilității care afirmă faptul că nu trebuie să se facă nici un fel de deosebire între tabelele de bază și vederi și
Principiul relativității bazei de date prin care tabelele bazei de date sunt considerate a fi tabele de bază din punct de vedere al utilizatorului (Date, 2000).
3.3.7. Inserarea, actualizarea și eliminarea
Datele pot fi extrase din cadrul unei baze de date relaționale sub forma unor mulțimi de date alcătuite pe baza rândurilor din unul sau mai multe tabele. Operațiile de inserare, actualizare și ștergere trebuie să fie aplicate pe orice astfel de mulțime la fel cum se aplică și pe un singur rând dintr-un tabel (Parkhurst, 2002).
3.3.8. Independența fizică de date
Acest lucru se referă la faptul că programele aplicație nu trebuie să fie afectate dacă au loc modificări în reprezentarea stocării datelor sau în metodele de acces la date. Programele aplicație sunt imune la modificările ce au loc în reprezentarea loc fizică sau în metodele de acces la date (Avery). Aceasta înseamnă faptul că structura fizică a datelor nu trebuie să provoace probleme utilizatorului care lucrează cu acele date.
3.3.9. Independența logică de date
Programele aplicație nu trebuie să fie afectate atunci când au loc modificări în structura tabelelor bazei de date, dacă modificările nu le afectează în mod direct. O vedere a utilizatorului asupra datelor nu trebuie să fie afectată nici ea în cazul modificării structurii logice a unei baze de date (de exemplu, adăugarea de coloane noi în tabele sau de tabele noi în baza de date) (Avery).
Date a definit independența logică de date ca reprezentând imunitatea utilizatorilor și a programelor acestora la modificările efectuate în structura logică a unei baze de date. În esență, asupra unei baze de date au loc două tipuri de operații: de adăugare de coloane sau tabele și de modificare a structurii tabelelor sau bazei de date. Nici una dintre cele două operații nu trebuie să afecteze utilizatorii sau programele acestora.
Operația de adăugare
De multe ori, unei baze de date trebuie să i se adauge fie coloane noi în cadrul tabelelor, fie tabele noi datorită apariției de date suplimentare ce trebuie implementate în baza de date originală. Ca urmare se pot identifica două tipuri de adăugări:
extinderea tabelelor prin apariția de atribute noi, de un anumit tip de dată specificat;
extinderea bazei de date prin apariția de tabele noi necesare introducerii de noi entități în baza de date.
Operația de reorganizare a structurii bazei de date
Uneori, apare necesitatea de modificare a structurii bazei de date, nu din cauza apariției de date noi, ci din apariția nevoii de reamplasare a anumitor date în mod diferit în cadrul tabelelor, conținutul acestora rămânând identic cu cel originar. (Date, 2000).
3.3.10. Independența integrității
Constrângerile de integritate specifice unei anumite baze de date relaționale trebuie să poată fi definite în sublimbajul relațional al datelor și înmagazinate în catalog, nu în programul aplicație. De asemenea trebuie să fie posibilă modificarea unor astfel de constrângeri așa cum cere logica aplicației fără a afecta celelalte aplicații (Date, 1991).
Constrângerile de integritate sunt reguli prin care sistemul de gestiune al bazelor de date împiedică baza de date să ajungă într-o stare inconsistentă. Potrivit celor afirmate de către Date în 2001, regula de aur a independenței integrității este: “Nu trebuie să fie permisă nici un fel de operație care să lase o anumită valoare într-o stare care să contrazică predicatul impus. În acest fel nu poate avea loc nici o tranzacție care ar încerca să lase baza de date într-o stare care să nu corespundă propriei condiții impuse.”
Constrângerile de integritate sunt:
Constrângeri NOT NULL
Această constrângere este preferată de standardul ISO în comenzile CREATE și ALTER TABLE. Constrângerea interzice înmagazinarea în baza de date a valorilor NULL, ceea ce înseamnă că nu se permite ca anumite coloane să fie goale (Connolly et al., 1999).
Clauza UNIQUE
Clauza UNIQUE specifică una sau mai multe coloane care identifică în mod unic fiecare înregistrare din cadrul unui tabel. În același timp, fiecare coloană ce apare în clauza UNIQUE trebuie să fie declarată ca fiind NOT NULL.
SQL anulează orice operație de inserare sau actualizare care are tendința de a genera valori duplicat în cheile candidat. Într-un tabel nu este permisă decât o singură cheie primară, iar clauza UNIQUE se folosește numai dacă a fost aleasă cheia primară și este necesar ca valorile altei coloane să fie unice.
Clauza PRIMARY KEY (integritatea entității)
Cheia primară a unui tabel trebuie să conțină o valoare unică nenulă pentru fiecare înregistrare introdusă în tabel. Standardul ISO impune integritatea entității prin intermediul clauzei cheii primare ce apare în instrucțiuni precum CREATE sau ALTER TABLE (Connolly et al., 1999).
FOREIGN KEY (integritatea referențială)
O cheie externă este un câmp dintr-un tabel ce corespunde coloanei cheie candidat dintr-un alt tabel. O valoare a cheii externe trebuie să aibă o valoare corespondentă în tabelul părinte. Tabelul ce conține cheia externă se numește tabelul referit, copil sau extern, în timp ce tabelul ce conține cheia candidat se numește tabelul de referință, primar, sau părinte (Rennhackkamp, 1996).
Integritatea referențială are semnificația faptului că nici o bază de date relațională nu poate conține valori necorespunzătoare ale cheii externe. Cheie externă necorespunzătoare reprezintă o valoare a cheii externe dintr-un tabel referit pentru care nu există valoare în tabelul de referință. Cu alte cuvinte, constrângerea specifică faptul că dacă B îl referă pe A, atunci A trebuie să existe. Date afirmă faptul că, de multe ori, nu este posibilă utilizarea unei interogări convenabile pentru a obține un anumit răspuns. Din acest motiv, trebuie să se poată specifica o acțiune referențială de tipul “CALL proc()”, în care proc reprezintă procedura creată de utilizator (Date, 2000).
Actualizările bazei de date au loc întotdeauna la nivel atomic, ceea ce înseamnă “totul sau nimic”, chiar dacă sunt implicate actualizări pe mai multe valori, ca în cazul acțiunii referențiale CASCADE (Date, 2000).
Standardul ISO propune introducerea cheii externe prin intermediul clauzei FOREIGN KEY ce apare în cadrul comenzilor de creare sau modificare a structurii unui tabel. De exemplu, dacă tabelul B are o cheie externă care face referire la o coloană din tabelul A, integritatea referențială interzice introducerea unei valori în tabelul B care nu are corespondent în tabelul A. În plus, regulile de integritate referențială pot avea în vedere și faptul că ori de câte ori se elimină o valoare din tabelul A, valorile corespunzătoare din tabelul B pot fi și ele eliminate, ceea ce este cunoscut sub denumirea de ștergere în cascadă. Regulile de integritate referențială mai pot specifica și faptul că ori de câte ori se modifică o valoare din tabelul A, toate valorile corespunzătoare din tabelul B sunt și ele modificate automat, ceea ce este cunoscut sub denumirea de actualizare în cascadă (Webopedia, Referential Integrity).
SQL prevede următoarele opțiuni ce pot fi alese în astfel de situații (Connolly et al., 1999):
1. CASCADE: prin ștergerea unei înregistrări din tabelul părinte automat se elimină toate înregistrările corespunzătoare din tabelul copil. Deoarece înregistrările eliminate pot conține o cheie candidat utilizată drept cheie externă în alt tabel, regulile cheii externe se aplică și în tabelul respectiv, ș.a.m.d.
2. SET NULL: șterge înregistrarea din tabelul părinte și provoacă setarea coloanelor cheie externă din tabelul copil la valoarea NULL, dar o astfel de operație este posibilă numai dacă coloanele cheii externe nu au setată opțiunea NOT NULL.
3. SET DEFAULT: șterge înregistrarea din tabelul părinte și provoacă setarea fiecărei componente a cheii externe din tabelul copil la valoarea implicită specificată, dar operația este valabilă numai dacă coloanele cheii primare au setată opțiunea DEFAULT.
4. NO ACTION: resping operația de ștergere din tabelul părinte, fiind opțiunea implicită dacă nu se introduc explicit reguli pentru ON DELETE.
Constrângerea CHECK
Există două tipuri de constrângeri CHECK. Una dintre ele este denumită constrângere de domeniu, deoarece stabilește mulțimea de valori pe care o poate lua un atribut, iar cealaltă se numește constrângerea logică utilizată cu scopul de a pune în evidență anumite condiții suplimentare (Connolly et al, 1999).
Standardul ISO prevede astfel de constrângeri ce pot fi introduse în cadrul comenzilor de creare sau modificare a unui tabel. Clauza CHECK permite definirea unei constrângeri pe o coloană sau pe întregul tabel. În cazul utilizării clauzei la nivel de coloană, aceasta nu poate face referire decât la coloana respectivă (Connolly et al, 1999).
Cel puțin următoarele două constrângeri trebuie să existe în orice bază de date relațională:
Integritatea entității: nici o componentă a cheii primare nu are voie să aibe valoarea NULL.
Integritatea referențială: pentru fiecare valoare nenulă a cheii externe din baza de date relațională, trebuie să existe o valoare corespunzătoare din același domeniu de valori și de același tip (cheia primară).
3.4. limbajul mysql
3.4.1. descriere
Bazele de date sunt folosite pentru stocarea informatiilor in vederea furnizarii ulterioare in functie de solicitarea primita.
MySQL este un sistem de baze de date functional independent.
In PHP exista functii pentru toate operatiile executate asupra bazelor de date MySQL.
Administrarea MySQL se poate face din linie de comanda sau folosind browserul si accesand aplicatia numita PHPMyAdmin scrisa in PHP.
3.4.2. Operații asupra bazelor de date
Cele mai uzuale operatii cu bazele de date sunt:
3.4.3. Tipuri de date MySQL
In MySQL spatiul alocat pe discul serverului este functie de tipul de date. Cateva din tipurile de date folosite in bazele de date MySQL sunt:
Pentru ca baza de date sa fuctioneze mai bine coloanelor li s-au adaugat modificatori de coloana.
Tipul de date intregi incep de la valori negative la pozitive. Daca se adauga optiunea UNSIGNED, care este un modificator de coloana, nu vor mai fi valori negative ci vor incepe de la 0.
Alti modificatori sunt:
_INCREMENT functioneaza cu orice tip intreg. La fiecare rand nou adaugat in baza de date numarul asociat va fi incrementat.
NULL inseamna fara valoare (diferit de spatiu sau zero).
NOT NULL inseamna ca orice inregistrare va fi considerata ceva.
PRIMARY este rolul primei coloane din tabel, totodata reprezentand elementul de referinta pentru fiecare linie.
3.4.4. Comenzi elementare MySQL
Cele mai frecvent utilizate comenzi MySQL sunt prezentate în coloana de mai jos. Ele sunt mult mai multe, dar aici nu doresc decât să fac o scurtă prezentare, urmând ca voi să studiați în detaliu comenzile utilizând manualul oficial pe care îl găsiți la adresa http://dev.mysql.com/doc/
Deși MySQL are suport pentru diacritice și setul de caractere 8859-2, este preferabil să nu folosiți diacritice în numele bazelor de date, tabelelor sau câmpurilor. De asemenea, nu puteți folosi ca nume de tabel sau de câmp cuvinte rezervate (nume de funcții, tipuri de caractere din MySQL precum CREATE, DROP sau COLUMN). Se pot folosi nume de tabele care conțin spații dar în practică trebuie să încadrați numele între back-ticks ` (semnul ` îl găsiți pe tasta aflată imediat sub Escape și înainte de 1).
Exemplu:
CREATE TABLE `tabel al carui nume are spatii` (`camp 1`, TEXT);
SHOW COLUMNS FROM `tabel al carui nume are spatii`;
Semnul * este definit în MySQL ca însemnând tot/toate.
Semnul % este folosit în interogările MySQL dacă vrem să găsim cuvântul oriunde în cadrul textului. Mai exact:
%cuvant_cautat – dacă vrem să afișeze toate cuvintele care se termină cu 'cuvantul_cautat' (pot fi și câteva caractere)
cuvant_cautat% – afișează toate cuvintele care încep cu 'cuvantul_cautat'
%cuvant_cautat% – afișează toate cuvintele care conțin 'cuvantul_cautat' oriunde în text.
Putem afla câte înregistrări sunt pentru un criteriu de selecție cu ajutorul lui count(). Putem afla astfel câte înregistrări sunt în total în tabel sau câte înregistrări sunt în tabel al căror câmp este cel cautat…
Cu ajutorul instrucțiunii GROUP BY putem "grupa" rezultatele astfel încât să nu vedem duplicatele și să vedem doar valorile unice. Pentru a limita numărul începând de la înregistrarea 10 încă 5 înregistrări).
Pentru ștergerea înregistrărilor dintr-un tabel se folosește comanda DELETE. Pentru ștergerea unui tabel sau a unei baze de date comanda este DROP.
Comanda UPDATE se folosește când vrem să modificăm conținutul unei înregistrări fără a o șterge.
Dacă dorim să schimbăm structura unui tabel existent sau să adăugăm alte coloane folosim comanda ALTER TABLE.
INDECSI – Cel mai folosit tip de index este id-ul. Id-ul este un număr unic de identificare pentru un element distinct (un rând) al unui tabel. Un exemplu de id din viața reală este numerotarea cd-urilor. Când aveți un cd nou îl numerotați și îl puneți în raft la sfârșit iar în catalog puteți să îl puneți sortat după titlu sau după numărul de ordine. La fel și într-o bază de date, puteți crea un câmp care să introducă automat un nr pentru fiecare rând nou adăugat în baza de date și la afișare puteți să îl folosiți (de exemplu la vizualizarea ultimilor 10 vizitatori folosiți id-ul).
Pentru a creea un index avem următoarele comenzi:
Să zicem că avem o bază de date numită lista cu un câmp caseta și adăugăm câmpul id_casete – comanda este următoarea:
ALTER TABLE `caseta` ADD `id_caseta` INT;
ALTER TABLE `caseta` CHANGE `id_caseta` `id_caseta` INT(11) UNSIGNED NOT NULL;
ALTER TABLE `caseta` ADD PRIMARY KEY (id_caseta);
ALTER TABLE `caseta` CHANGE `id_caseta` `id_caseta` INT(11) UNSIGNED DEFAULT "0" NOT NULL AUTO_INCREMENT;
Și din acest moment, orice casetă nouă introdusă va avea automat un nr de ordine. Este posibil ca toată înșiruirea de comenzi de mai sus să se poată face printr-o singură linie de cod, dar este mai sigur să faceți câte o modificare în parte decât toate odată, pentru a detecta eventualele erori. Este bine să creați un id la începutul tabelului, când nu aveți intrări în baza de date, pentru a face incrementarea automat, altfel e posibil să vă dea erori. Cu ajutorul id-ului puteți afișa de exemplu noutațile, cu o comandă de genul – afișează ultimele 10 intrări sortate după id…, știind că întotdeauna ultima intrare are numărul cel mai mare…
Cât de mare poate fi un tabel?
MySQL stochează fizic datele unui tabel într-un fișier pe hard disc și cu cât tabelul e mai mare, cu atât mărimea acestui fișier crește. Versiunea 3.22 a MySQL are o limită de 4 GB pentru mărimea unui tabel. În versiunile superioare această limită este extinsă până la 8 milioane TB pentru tipul de tabel MyISAM. Cu toate acestea, sistemele de operare pot avea propriile limitări ale mărimii fișierelor. Mărimea impicită a tabelelor MySQL este de aproximativ 4 GB. Puteți verifica mărimea maximă pentru un tabel cu ajutorul
3.4.5. comenzi pentru interogarea bazelor de date. fraza SELECT
În SQL o interogare se formulează printr-o frază SELECT. Aceasta prezintă trei clauze principale: SELECT, FROM și WHERE.
SELECT corespunde operatorului proiecție din algebra relațională, fiind utilizată pentru desemnarea listei de atribute (coloanele) din tabela-rezultat;
FROM este cea care permite enumerarea relațiilor din care vor fi extrase informațiile aferente consultării;
prin WHERE se desemnează predicatul selectiv al algebrei relaționale, relativ la atribute ale relațiilor care apar în clauza FROM.
La modul general o consultare simplă în SQL poate fi prezentată astfel:
SELECT C1, C2, …, Cn
FROM R1, R2, …, Rm
WHERE P
Execuția unei fraze SELECT se concretizează în obținerea unei tabele (relații) rezultat. Acestă poate fi o tabelă propriu-zisă sau o tabelă temporară (care, de obicei, nu poate fi actualizată), dar și o tabelă derivată (imagine). Uneori tabela rezultat poate fi obținută sub "forma" unei variabile-tablou.
Ci – reprezintă coloanele (care sunt atribute sau expresii de atribute) tabelei-rezultat;
Rj – sunt relațiile ce trebuie parcurse pentru obținerea rezultatului;
P – este predicatul (condiția) simplu sau compus ce trebuie îndeplinit de tupluri pentru a fi incluse în tabela-rezultat.
Când clauza WHERE este omisă, se consideră implicit că predicatul P are valoarea logică "adevărat".
Dacă în locul coloanelor C1, C2, … Cn apare simbolul "*", în tabela-rezultat vor fi incluse toate coloanele (atributele) din toate relațiile specificate în clauza FROM. De asemenea, în tabela-rezultat, nu este obligatoriu ca atributele să prezinte nume identic cu cel din tabela enumerată în clauza FROM. Schimbarea numelui se realizează prin opțiunea AS.
Rezultatul unei fraze SELECT l vom considera ca fiind sub forma unei tabele oarecare. Trebuie avut n vedere, ns, c rezultatul interogrii poate fi obinut i sub forma unei tabele temporare sau chiar a unei variabile-tablou (matrice). n unele SGBD-uri, cum ar fi FoxPro, formatul general al frazei SELECT conine i clauza INTO.
SELECT …
FROM …
INTO destinație
WHERE …
Destinație specific dacă se va obține o tabel "normal", o tabel temporar (tabel care se terge automat la nchiderea sa) sau o variabil-tablou. Dac clauza INTO nu este utilizat, atunci n urma interogrii se obine o tabel temporar cu numele predeterminat (Query).
Uneori, tabela rezultat ("normal" sau temporar) "ncalc" poruncile modelului relaional. Conform restriciei de entitate, ntr-o relaie nu pot exista dou linii identice. Or, n SQL, tabela obinut dintr-o consultare poate conine dou sau mai multe tupluri identice.
Spre deosebire de algebra relațională, în SQL nu se elimină automat tuplurile identice (dublurile) din tabela-rezultat. Pentru aceasta este necesară utilizarea opțiunii DISTINCT:
SELECT DISTINCT C1, C2, …, Cn
FROM R1, R2, …, Rm
WHERE P
Figura nr. 6.1. Baza de date utilizată în exemple
În concluzie, o frază SELECT, în forma în care a fost prezentată, corespunde:
unei selecții algebrice (clauza WHERE – P)
unei proiecții (SELECT – Ci)
unui produs cartezian (FROM – R1 R2 … Rm)
și conduce la obținerea unei noi relații (tabele-rezultat) cu n coloane, fiecare coloană fiind:
un atribut din R1, R2, …, Rm sau
o expresie calculată pe baza unor atribute din R1, R2, …, Rm.
În exemplele incluse în acest capitol se va utiliza baza de date prezentată în figura 6.1.
Exemplu
Care este, pentru fiecare factură emisă, valoarea fără TVA ?
SELECT NrFactură, ValoareTotală – TVAColectata AS ValFaraTVA
FROM FACTURIEMISE
Tabela rezultat din figura 6.2 conține două atribute: NrFactură și ValFaraTVA. Ultimul este un câmp calculat.
Figura nr. 6.2. Exemplu de câmp calculat (ValFaraTVA)
Interogări care utilizează operatorii asambliști din algebra relațională
Reuniunea
SELECT *
FROM R1
SELECT *
FROM R2
Operatorul pentru reuniune este deci UNION. De remarcat că, la reuniune, SQL elimină automat dublurile, deci nu este necesară utilizarea clauzei DISTINCT. Operatorul UNION este prezent în toate SGBD-urile importante.
Intersecția
Pentru realizarea intersecției a două tabele, R1 și R2 se utilizează operatorul INTERSECT:
SELECT *
FROM R1
INTERSECT
SELECT *
FROM R2
Dacă în produsele profesionale, precum DB2 (IBM) sau Oracle operatorul este prezent, în schimb multe din cele din categoria “ușoară”, precum Visual Fox Pro, INTERSECT rămâne un deziderat, funcționalitatea sa realizându-se prin subconsultări (operatorii IN și EXISTS) sau, uneori, prin joncțiune.
Diferența
Diferența dintre tabelele R1 și R2 se realizează utilizând operatorul MINUS sau EXCEPT. Fraza SELECT următoare funcționează în Oracle.
SELECT *
FROM R1
MINUS
SELECT *
FROM R2
În DB2 MINUS trebuie înlocuit cu EXCEPT, iar în Visual FoxPro există nici MINUS și nici EXCEPT, astfel încât, ca și în cazul intersecției, este necesar a se recurgere la alți operatori, precum IN sau EXISTS.
Produsul cartezian
În SQL nu există operator explicit pentru efectuarea produsului cartezian. Dacă în clauza FROM apar două relații, R1 și R2, atunci, în lipsa unei condiții de joncțiune formulată în clauza WHERE, tabela rezultat va conține liniile obținute din produsul cartezian R1 R2.
SELECT *
FROM R1, R2
Interogări care utilizează operatorii relaționali din algebra relațională
Selecția
Exemplu 1
Care sunt localitățile din județul Iași în care firma are clienți ?
Tabela în care se află rezultatul și asupra căreia se aplică predicatul de selecție este LOCALITĂȚI. Predicatul este Județ = "Iași". Fraza SELECT va avea forma:
SELECT *
FROM LOCALITĂȚI
WHERE Județ = ""
Exemplu 2
Care dintre facturile emise după 23.06.98 prezintă valoarea mai mare sau egală cu 3 000 000 lei ?
SELECT *
FROM FACTURIEMISE
WHERE Data > {23.06.2000} AND ValoareTotala >= 3000000
După cum se observă, operatorul AND a fost utilizat pentru a introduce un "ȘI" logic, după cum OR se utilizează pentru “SAU” logic. În SQL, pentru comparare, în afara operatorilor "clasici" specificați mai sus, pot fi utilizați și alți operatori, dintre care în acest paragraf ne vom opri la:
BETWEEN (între, cuprins între),
LIKE (ca și, la fel ca),
IN (în) și
IS NULL.
Operatorul BETWEEN
Acest operator permite specificarea unui interval de valori în care trebuie să se încadreze câmpul/expresia testată. Acest interval se referă la valori numerice sau la date calendaristice.
Exemplu 3
Se reformulează ultima interogare:
Care sunt facturile emise după 23.06.2000 și care au valoarea cuprinsă între 3 000 000 și 4 000 000 lei ?
Fără operatorul BETWEEN fraza SELECT se scrie:
SELECT *
FROM FACTURIEMISE
WHERE Data > {23.06.2000} AND
ValoareTotala >= 3000000 AND ValoareTotala <= 4000000
Utilizând operatorul BETWEEN se poate scrie:
SELECT *
FROM FACTURIEMISE
WHERE Data > {23.06.2000} AND ValoareTotala BETWEEN 3000000 AND 4000000
Operatorul LIKE
Acest operator se folosește pentru a compara un atribut de tip șir de caractere (ex. NumeClient, Adresa, Localitate) cu un literal ( de tip șir de caractere). Astfel, dacă se dorește obținerea unei tabele-rezultat care să conțină numai clienții ai căror nume începe cu litera M, putem scrie predicatul din clauza WHERE sub forma: NumeClient LIKE "M%". Deoarece după litera M apare semnul "%", se vor extrage din tabela CLIENȚI toate tuplurile pentru care valoarea atributului NumeClient începe cu litera M, indiferent de lungimea acestuia (ex. MELCRET, MIGAS, MITA, MATSUSHITA etc.). Despre semnul "%" se spune că este un specificator multiplu, joker sau mască.
Un alt specificator multiplu utilizat în multe versiuni SQL este liniuța de subliniere ("_"). Spre deosebire de "%", "_" substituie un singur caracter. Diferența dintre cei doi specificatori multipli este pusă în evidență în exemplele următoare.
Exemplu 4
Care sunt clienții ai căror nume este format din șapte caractere, începe cu litera A și sunt societăți cu răspundere limitată (SRL-uri) ?
SELECT *
FROM CLIENȚI
WHERE NumeClient LIKE "A__ SRL"
Rezultatul va fi cel din figura 6.3.
Figura nr. 6.3. Utilizarea specificatorului multiplu "_"
Dacă s-ar fi utilizat simbolul "%":
SELECT *
FROM CLIENȚI
WHERE NumeClient LIKE "A%SRL",
rezultatul ar fi fost cel din figura 6.4.
Figura nr. 6.4. Utilizarea specificatorului multiplu "%"
În concluzie, "_" înlocuiește (substituie) un singur caracter, în timp ce "%" înlocuiește un șir de caractere de lungime variabilă (între 0 și n caractere). Cei doi specificatori multipli pot fi utilizați împreună.
Operatorul IN
Format general:
expresie1 IN (expresie2, expresie3, …)
Rezultatul evaluării unui predicat ce conține acest operator va fi "adevărat" dacă valoarea expresiei1 este egală cu (cel puțin) una din valorile: expresie2, expresie3, … Este util atunci când condițiile de selecție sunt mai complexe.
Exemplu 6
Care sunt localitățile din județele Iași și Vaslui?
Fără utilizarea operatorului IN interogarea se scrie:
SELECT *
FROM LOCALITĂȚI
WHERE Județ = "" OR Județ = "Vaslui"
Utilizând operatorul IN:
SELECT *
FROM LOCALITĂȚI
WHERE Județ IN ("", "Vaslui")
Operatorul IS NULL
O valoare nulă este o valoare nedefinită. Este posibil ca la adăugarea unei linii într-o tabelă, valorile unor atribute să fie necunoscute. În aceste cazuri valoarea atributului pentru tuplul respectiv este nulă. Reamintim că, prin definiție, nu se admit valori nule pentru grupul atributelor care constituie cheia primară a relației.
Exemplu 7
Dacă se dorește aflarea clienților pentru care nu s-a introdus adresa, interogarea se poate scrie:
SELECT *
FROM CLIENTI
WHERE Adresa IS NULL
Cum în baza noastră de date, numai clientului OCCO SRL nu-i cunoaștem adresa, rezultatul interogării este cel din figura 6.5.
Figura nr. 6.5. Extragerea valorilor NULLe
Observații
Valoarea NULL nu se confundă cu valoarea zero (pentru atributele numerice) sau cu valoarea "spațiu" (pentru atributele de tip șir de caractere)
Operatorul NULL se utilizează cu IS și nu cu semnul "=". Dacă s-ar utiliza forma expresie = NULL și nu expresie IS NULL, rezultatul evaluării va fi întotdeauna fals, chiar dacă expresia nu este nulă !
Proiecția. Opțiunea ORDER BY
Coloanele tabelei-rezultat al consultării sunt specificate în clauza SELECT, fiind separate prin virgulă.
Exemplu 1
Care sunt județele în care firma are clienți ?
Este necesară parcurgerea relației LOCALITĂȚI, singurul atribut care interesează fiind Județ. Deoarece SQL nu elimină dublurile automat, dacă se dorește ca în tabela-rezultat o localitate să figureze o singură dată, se utilizează opțiunea DISTINCT:
SELECT DISTINCT Județ
FROM LOCALITĂȚI
Exemplu 2
Care este denumirea fiecărei localități și județul în care se află ?
SELECT Localitate, Județ
FROM LOCALITĂȚI
Prezentarea localităților în ordinea alfabetică a numelui acestora este posibil prin apelnd la clauza ORDER BY:
SELECT Localitate, Județ
FROM LOCALITĂȚI
ORDER BY Localitate
Pentru ordonarea liniilor tabelei-rezultat în funcție de județ și, în cadrul aceluiași județ, în ordinea inversă a localității (de la Z la A), fraza SELECT se formulează astfel:
SELECT *
FROM LOCALITĂȚI
ORDER BY Județ ASCENDING, Localitate DESCENDING
Figura nr. 6.6. Clauza ORDER BY
Opțiunile ASCENDING (crescător) și DESCENDING (descrescător) indică deci modul în care se face ordonarea tuplurilor tabelei-rezultat al interogării.
Prioritatea de ordonare este stabilită prin ordinea atributelor specificate în ORDER BY: ordonarea "principală" se face în funcție de valorile primului atribut specificat; în cadrul grupelor de tupluri pentru care valoarea primului atribut este identică, ordinea se stabilește după valoarea celui de-al doilea atribut specificat ș.a.m.d.
Dacă în ORDER BY lipsesc opțiunile ASCENDING/DESCENDING, ordonarea se face crescător.
oncțiunea
SQL nu prezintă clauze sau operatori speciali pentru realizarea theta-joncțiunii, echi-joncțiunii sau joncțiunii naturale. Dar, așa cum am văzut, o joncțiune este o combinație de produs cartezian și selecție.
Exemplu 1
Revenind la exemplele din algebra relațională, echi-joncțiunea tabelelor FURNIZOR1 și FURNIZOR2 în SQL se realizează prin fraza SELECT:
SELECT *
FROM FURNIZOR1, FURNIZOR2
WHERE FURNIZOR1.CodF = FURNIZOR2.CodF
Observație:
În SQL2, echijoncțiunea poate fi realizată prin clauza INNER JOIN plasată în clauza FROM. Astfel, ultima frază SELECT se poate redacta, în SQL2, fără clauza WHERE:
SELECT *
FROM FURNIZOR1 INNER JOIN FURNIZOR2 ON
FURNIZOR1.CodF = FURNIZOR2.CodF
Exemplu 2
Care sunt clienții din municipiul Focșani ?
SELECT *
FROM CLIENȚI INNER JOIN LOCALITĂȚI
ON CLIENȚI.CodPostal = LOCALITĂȚI.CodPostal
WHERE Localitate=”Focsani”
Produsul cartezian al tabelelor CLIENȚI și LOCALITĂȚI este prezentat în figura 6.7.
Figura nr. 6.7. Produsul cartezian CLIENȚI LOCALITĂȚI
Din cele 32 de linii sunt selectate cele care îndeplinesc condiția de joncțiune, CLIENȚI.CodPostal = LOCALITĂȚI.CodPostal, și pe cea suplimentară – Localitate=”Focsani”. În final, rezultatul este cel din figura 6.8.
Figura nr. 6.8. Rezultatul final al joncțiunii și al selecției suplimentare
Exemplu 3
Care sunt facturile emise clienților din județul Iași ?
SELECT NrFactura
FROM FACTURIEMISE, CLIENȚI, LOCALITĂȚI
WHERE FACTURIEMISE.CodClient = CLIENȚI.CodClient
AND CLIENȚI.CodPostal = LOCALITĂȚI.CodPostal
AND Județ=”Iași”
Soluția este echivalentă cu următoarea:
SELECT NrFactura
FROM FACTURIEMISE FE INNER JOIN CLIENȚI C
ON FE.CodClient = C.CodClient
INNER JOIN LOCALITĂȚI L
ON C.CodPostal = L.CodPostal
WHERE Județ=””
Exemplu 4
Care sunt facturile emise în aceeași zi ca și factura 111113 ?
Problema propusă poate fi rezolvată relativ ușor folosind o subconsultare, după cum va fi prezentat în paragraful următor. Până una-alta, soluția pe care o avem în acest moment la îndemână se bazează pe autojoncțiune. Autojoncțiune înseamnă joncțiunea unei tabele cu ea-însăși, practic, joncțiunea a două instanțe ale unei aceleași tabele:
SELECT FE1.NrFactura, FE1.Data
FROM FACTURIEMISE FE1 INNER JOIN FACTURIEMISE FE2
ON FE1.Data= FE2.Data AND FE2.NrFactura=111113
Soluția de mai sus conduce la rezultatul din figura 6.9. Să vedem prin ce mecanism.
Figura nr. 6.9. Facturile emise în aceeași zi ca și 111113
Joncțiunea celor două instanțe, FE1 și FE2, ale tabelei FACTURIEMISE după condiția FE1.Data = FE2.Data:
SELECT *
FROM FACTURIEMISE FE1 INNER JOIN FACTURIEMISE FE2
ON FE1.Data= FE2.Data
conduce la un rezultat precum cel din figura 6.10.
Figura nr. 6.10. Auto-joncțiunea, după valorile Data, tabelei FACTURIEMISE
Din cele 38 de linii, prin predicatul FE2.NrFactura=111113 rămân numai 3, cele din figura 6.9.
Exemplu 5
Care sunt clienții cărora NU le-am întocmit facturi pe 18/06/2000 ?
La această problemă se pot formula mai multe soluții. Una ar fi bazată pe diferența dintre toți clienții (extrași din tabela CLIENȚI) și cei cărora le-am trimis facturi pe 18 iunie. Ținând seama că numele clientului este cheie alternativă, deci unic, se poate scrie:
SELECT NumeClient
FROM CLIENTI
MINUS
SELECT NumeClient
FROM CLIENTI INNER JOIN FACTURIEMISE
ON CLIENTI.CodClient=FACTURIEMISE.CodClient AND Data={^2000/06/18}
O asemenea soluție funcționează în Oracle (folosind funcția de conversie TO_DATE pentu constantă), DB2 (înlocuind, în plus, MINUS cu EXCEPT), nu însă și în Visual FoxPro. Având în vedere că nu avem cunoștințe privind subconsultările, putem recurge la un artificiu bazat pe o formă interesanța a joncțiunii, și anume joncțiunea externă.
Să examinăm fraza SELECT următoare și rezultatul acesteia din figura 6.11.
SELECT *
FROM CLIENTI C LEFT OUTER JOIN FACTURIEMISE FE
ON C.CodClient=FE.CodClient AND Data={^2000/06/18}
Figura nr. 6.11. O joncțiune externă
Prima observație: în rezultat sunt incluse toți clienții, adică, toate înregistrările din tabela CLIENȚI. A doua observație: joncțiunea nu mai este de tip INNER și LEFT OUTER, adică externă la stânga. Cum dintre CLIENȚI și FACTURIEMISE, cea de la stânga este prima, rezultă că în rezultat sunt extrase toate liniile din aceasta, chiar dacă nu au linii corespondente în tabela din dreapta. În cazul nostru, TEXTILA SA, MODERN SRL, INTEGRATA SA, AMI SRL șî AXON SRL nu au făcut “cumpărături” de la firma noastră pe 18 iunie 2000. Ne dăm seama de acest lucru observând că pe liniile coresponde acestora, valorile atributelor preluate din FACTURIEMISE sunt NULL.
Astfel încât, pentru a răspunde punctual la problema pusă, ar trebui extrase liniile în care, în urma joncțiunii externe, FE.NrFactură (sau oricare alt atribut din FE) este NULL. Paradoxal sau nu, fraza următoare nu obține rezultatul scontat în VFP:
SELECT *
FROM CLIENTI C LEFT OUTER JOIN FACTURIEMISE FE
ON C.CodClient=FE.CodClient AND Data={^2000/06/18}
WHERE FE.NrFactura IS NULL
În schimb, se poate folosi un artificiu prin întrebuințarea funcției NVL:
SELECT *
FROM CLIENTI C LEFT OUTER JOIN FACTURIEMISE FE
ON C.CodClient=FE.CodClient AND Data={^2000/06/18}
WHERE NVL(FE.NrFactura,0) = 0
Funcția NVL convertește valorile nule ale atributului NrFactura în 0. Principial, soluția bazată pe NVL are același mecanism ca și precedenta interogare. Cu singura diferență că… funcționează, după reiese din figura 6.12.
Figura nr. 6.12. Clienții fără facturi pe 18 iunie 2000
Firește, pentru a obține numai numele clienților, este necesară înlocuirea asteriscului din clauza SELECT cu atributul NumeClient.
Ar mai fi de adăugat că există trei tipuri de joncțiune externă: la stânga (LEFT OUTER JOIN), la dreapta (RIGHT OUTER JOIN) și totală (FULL OUTER JOIN). La joncțiunea externă la dreapta sunt extrase liniile echi-joncțiunii plus liniile tabelei din dreapta ce nu îndeplinesc condiția formulată prin predicatul de joncțiune. Joncțiunea externă totală reprezintă, în fapt, reuniunea (cu eliminarea dublurilor) joncțiunilor la stânga și la dreapta.
Sub-consultări. Operatorul IN
O altă facilitate deosebit de importantă a limbajului SQL o constituie posibilitatea includerii (imbricării) a două sau mai multe fraze SELECT, astfel încât pot fi formulate interogări cu mare grad de complexitate.
Operatorul IN poate fi utilizat și pentru includerea unei fraze SELECT într-o altă frază SELECT.
Exemplu 1
Care sunt facturile emise în aceeași zi în care a fost întocmită factura 111113 ?
SELECT *
FROM FACTURIEMISE
WHERE Data IN
(SELECT Data
FROM FACTURIEMISE
WHERE NrFactură=111113)
Sub-consultarea
SELECT Data
FROM FACTURIEMISE
WHERE NrFactură=111114
are ca rezultat o tabelă alcătuită dintr-o singură coloană (Data) și o singură linie ce conține valoarea atributului Data pentru factura 111113, ca în figura 6.13:
Figura nr. 6.13. Rezultatul sub-consultării
Clauza WHERE Data IN determină căutarea în tabela FACTURIEMISE a tuturor tuplurilor (liniilor) care au valoarea atributului Data egală cu una din valorile tuplurilor (în cazul nostru, egală cu valoarea tuplului) din tabela obținută prin "sub-consultare" (în cazul nostru, tabela din figura 6.13). Cu alte cuvinte, în acest caz WHERE Data IN va selecta toate facturile pentru care data emiterii este 18/06/2000 – figura 6.14.
Figura nr. 6.14. Facturile emise în aceeași zi ca și 111113
Exemplu 2
Care sunt facturile emise în alte zile decât cea în care a fost întocmită factura 111113?
SELECT *
FROM FACTURIEMISE
WHERE Data NOT IN
(SELECT Data
FROM FACTURIEMISE
WHERE NrFactură=111113)
S-a utilizat negația, testându-se non-apartenența la o relație creată printr-o sub-frază SELECT (vezi figura nr. 6.15).
Figura nr. 6.15. Facturile emise în alte zile decât factura 111113
Exemplu 3
Care sunt clienții cărora li s-au trimis facturi întocmite în aceeași zi cu factura 111113?
SELECT DISTINCT NumeClient
FROM CLIENȚI
WHERE CodClient IN
(SELECT CodClient
FROM FACTURIEMISE
WHERE Data IN
(SELECT Data
FROM FACTURIEMISE
WHERE NrFactură=111113))
Am ilustrat modul în care pot fi imbricate (înlănțuite, incluse) trei fraze SELECT. Soluția este valabilă în SGBD-urile profesionale (DB2, Oracle…), nu însă și în VFP, în care orice interogare poate fi desfășutata pe maximum două nivele (SELECT-ul principal, plus un nivel de sub-consultări). Pentru a reduce numărul “straturilor” de corelare, se poate folosi, în acest caz, joncțiunea:
SELECT DISTINCT NumeClient
FROM CLIENȚI, FACTURIEMISE
WHERE CLIENȚI.CodClient=FACTURIEMISE.CodClient
AND Data IN
(SELECT Data
FROM FACTURIEMISE
WHERE NrFactura=111113)
Rezultatul din figura 6.16 demonstrează că soluția este viabilă.
Figura nr. 6.16. Clienți pentru care există măcar o factură
întocmită în aceeași zi cu 111113
Se poate reține, ca regulă generală, că aproape orice consultare poate fi redactată în mai multe moduri, în funcție de experiența și imaginația celui care o formulează.
Funcții de agregare: COUNT, SUM, AVG, MAX, MIN
Formatul general al unei fraze SELECT ce conține funcții predefinite este:
SELECT funcția-predefinită1, … , funcția-predefinităN
FROM listă-tabele
WHERE condiții
Rezultatul oricărei fraze SELECT este o nouă relație (tabelă). În lipsa opțiunii GROUP BY, dacă în clauza SELECT este prezentă o funcție predefinită, tabela rezultat va conține o singură linie.
Funcția COUNT contorizează valorile unei coloane, altfel spus, numără, într-o relație, câte valori diferite de NULL are coloana specificată.
Exemplu 1
Câți clienți are firma ?
SELECT COUNT (CodClient) AS Nr_Clienti
FROM CLIENTI
În funcția COUNT se poate utiliza ca argument, în locul numelui unei coloane, semnul *; în acest caz se va determina câte linii are tabela la care se aplică funcția respectivă.
Exemplu 2
La câți clienți s-au trimis facturi ?
SELECT COUNT ()
FROM CLIENTI
WHERE CodClient IN
(SELECT CodClient
FROM FACTURIEMISE)
Rezultatul corect poate fi însă obținut și prin utilizarea clauzei DISTINCT astfel:
SELECT COUNT (DISTINCT CodClient)
FROM FACTURIEMISE
Funcția SUM calculează suma valorilor unei coloane.
Exemplu 3
Care este valoarea totală a facturilor emise ?
SELECT SUM (ValoareTotala) AS Total_FP
FROM FACTURIEMISE
Figura 6.17. Totalul vânzărilor
Exemplu 4
Care este totalul valorii facturilor trimise clientului AXON SRL ?
SELECT SUM (ValoareTotala) AS Total_FE_AXON
FROM FACTURIEMISE, CLIENTI
WHERE FACTURIEMISE.CodClient = CLIENTI.CodClient
AND NumeClient = "AXON SRL"
Funcțiile MAX și MIN. Determină valorile maxime, respectiv minime ale unei coloane în cadrul unei tabele.
Exemplu 5
Care este cea mai mică valoare a unei facturi emise ?
SELECT MIN(ValoareTotala)
FROM FACTURIEMISE
Exemplu 6
Care este factura emisă ce are cea mai mare valoare ?
SELECT NrFactura, ValoareTotala
FROM FACTURIEMISE
WHERE ValoareTotala =
(SELECT MAX (ValoareTotala)
FROM FACTURIEMISE)
Subconsultarea extrage valoarea totală maximă a unei facturi, valoare ce va fi utilizată ca argument pentru SELECT-ul principal. Rezultatul este cel din figura 6.18.
Figura nr. 6.18. Factura cea mai valoroasă
Atenție ! Varianta următoare nu este corectă:
SELECT NrFactura, MAX(ValoareTotala )
FROM FACTURIEMISE
Dacă în Oracle sau DB2 la execuția acestei interogări se afișează un mesaj de eroare, în Visual FoxPro nu, așa că unii utilizatori s-ar putea baza pe rezultatul afișat.
Gruparea tuplurilor. Clauzele GROUP BY și HAVING
SQL permite utilizarea clauzei GROUP BY pentru a forma grupe (grupuri) de tupluri ale unei relaii, pe baza valorilor comune ale unei coloane. În frazele SELECT formulate până în acest paragraf, prin intermediul clauzei WHERE au fost selectate tupluri din diferite tabele.
Prin asocierea unei clauze HAVING la o clauză GROUP BY este posibilă selectarea anumitor grupe de tupluri ce îndeplinesc un criteriu.
Rezultatul unei fraze SELECT ce conține clauza GROUP BY este o tabelă care va fi obținută prin regruparea tuturor liniilor din tabelele enumerate în FROM, care prezintă o aceeași valoare pentru o coloană sau un grup de coloane.
Formatul general este:
SELECT coloană 1, coloană 2, …., coloană m
FROM tabelă
GROUP BY coloană-de-regrupare
Exemplu 1
Care este totalul zilnic al valorii facturilor emise ?
SELECT Data, SUM (ValoareTotala) AS Total_Zilnic
FROM FACTURIEMISE
GROUP BY Data
În acest caz tabela-rezultat va avea un număr de linii egal cu numărul de date calendaristice distincte din tabela FACTURIEMISE. Pentru toate facturile aferente unei zile se va calcula suma valorilor, datorită utilizării funcției SUM(ValoareTotala).
Succesiunea pailor este urmtoarea:
1. Se ordoneaz liniile tabelei FACTURIEMISE n funcie de valoarea atributului Data – figura 6.19.
Figura nr. 6.19. Pasul 1 al grupării
2. Se formeaz cte un grup pentru fiecare valoare distinct a atributului Data – vezi figura 6.20.
Figura nr. 6.20. Al doilea pas al grupării
3. Pentru fiecare din cele nou grupuri se calculeaz suma valorilor atributului ValoareTotala. Tabela rezultat va avea nou linii, ca în figura 6.21.
Figura nr. 6.21. Rezultatul final al grupării
Exemplu 2
Care este numărul facturilor emise pentru fiecare client ?
SELECT NumeClient, COUNT(NrFactura)
FROM FACTURIEMISE INNER JOIN CLIENTI
ON FACTURIEMISE.CodClient = CLIENTI.CodClient
GROUP BY FACTURIEMISE.CodClient
Până la standardul SQL99 și publicarea Amendamentului OLAP la acest standard, în SQL nu pot fi calculate, prin GROUP BY, subtotaluri pe mai multe niveluri. Pentru aceasta este necesară scrierea de programe în SGBD-ul respectiv.
Clauza HAVING permite introducerea unor restricții care sunt aplicate grupurilor de tupluri, deci nu tuplurilor "individuale", așa cum "face" clauza WHERE. Din tabela rezultat sunt eliminate toate grupurile care nu satisfac condiția specificată.
Clauza HAVING "lucrează" împreună cu o clauză GROUP BY, fiind practic o clauză WHERE aplicată acesteia.
Formatul general este:
SELECT coloană 1, coloană 2, …. , coloană m
FROM tabelă
GROUP BY coloană-de-regrupare
HAVING caracteristică-de-grup
Exemplu 3
Pentru facturile emise intereseaz valoarea zilnic a acestora (n funcie de data la care au fost ntocmite, dar numai dac aceasta (valoarea zilnic) este de mai mare de cinci milioane lei.
SELECT Data, SUM(ValoareTotala)
FROM FACTURIEMISE
GROUP BY Data
HAVING SUM(ValoareTotala) > 15000000
La execuia acestei fraze, se parcurg cei trei pai prezentai la exemplul 1, apoi, din cele nou tupluri obinute prin grupare, sunt extrase numai cele care ndeplinesc condiia SUM(ValoareTotala)>15000000. Rezultatul final este cel din figura 6.22.
Figura 6.22. Rezultatul consultării – exemplul 3
Exemplu 4
Să se afișeze ziua în care s-au întocmit cele mai multe facturi.
SELECT Data
FROM FACTURIEMISE
GROUP BY Data
HAVING COUNT(*) >= ALL
(SELECT COUNT(*)
FROM FACTURIEMISE
GROUP BY Data)
Din păcate, nici acest tip de interogare (prezența subconsultărilor în clauza HAVING) nu este agreat de Visual FoxPro, astfel încât este necesară utilizarea mai multor fraze SELECT și salvarea rezultatelor intermediare fie în tabele derivate (view-uri), fie în cursoare (NR_PE_ZILE) care, în VFP sunt tabele temporare a căror viață este limitată de închiderea lor, explicită sau implicită:
SELECT Data, COUNT(*) AS Nr ;
FROM FACTURIEMISE ;
INTO CURSOR NR_PE_ZILE ;
GROUP BY Data
SELECT Data, Nr ;
FROM NR_PE_ZILE ;
WHERE Nr >= ;
(SELECT MAX(Nr) ;
FROM NR_PE_ZILE)
Conținutul cursorului NR_PE_ZILE, precum și rezultatul final sunt cele din figura 6.23.
Figura 6.23. Obținerea în VFP a zilei cu cele mai multe facturi
Comenzi pentru actualizarea bazelor de date
SQL prezintă comenzi specifice pentru modificarea conținutului unei tabele, înțelegând prin aceasta trei acțiuni prin care se actualizează baza:
a) adăugarea de noi linii la cele existente într-o tabelă,
b) ștergerea unor linii,
c) modificarea valorii unui atribut.
Adăugarea de înregistrări
Exemplu 1
Să presupunem că, la un moment dat, întreprinderea vinde produse și firmei RODEX SRL care are sediul pe strada Sapienței, nr.44 bis, în localitatea Iai.
Acest nou client trebuie "introdus" în baza de date, operațiune care în SQL, se realizează prin comanda:
INSERT
INTO CLIENȚI
VALUES (1009, ‘RODEX SRL’, ‘Sapienței, 44 bis’, ‘6600’)
Fraza INSERT de mai sus poate fi scrisă și sub forma
INSERT
INTO CLIENȚI (CodClient, NumeClient, Adresa, CodPostal)
VALUES (5009, ‘RODEX SRL’, ‘Sapienței 44 bis’, 6600).
După cum se observă, după numele tabelei (CLIENȚI) au fost enumerate toate atributele pentru care se introduc valori prin clauza VALUES. Dacă nu s-ar fi cunoscut adresa clientului RODEX, atunci fraza INSERT ar fi avut una din formele:
INSERT
INTO CLIENȚI (CodClient, NumeClient, Adresa, CodPostal)
VALUES (5009, "RODEX SRL", NULL, ‘6600’)
sau
INSERT
INTO CLIENȚI (CodClient, NumeClient, CodPostal)
VALUES (5009, ‘RODEX SRL’, ‘6600’)
În noua linie a tabelei CLIENȚI valoarea atributului Adresa va fi NULL.
Ștergerea de înregistrări
Operațiunea de eliminarea a una sau mai multe linii dintr-o tabelă, pe baza unui predicat, se realizează în SQL prin comanda DELETE care are sintaxa:
DELETE
FROM nume-tabelă
WHERE predicat
Exemplu 2
Să se elimine din tabela CLIENȚI linia aferentă clientului MODERN SRL (cod 1002).
DELETE
FROM CLIENȚI
WHERE CodClient = 1002
Exemplu 3
Să se șteargă datele referitoare la fiecare vânzare de produs pentru clienții din orașul Focșani.
DELETE
FROM FACTURIEMISE
WHERE CodClient IN
(SELECT CodClient
FROM CLIENȚI, LOCALITĂȚI
WHERE CLIENȚI.CodPostal=LOCALITĂȚI.CodPostal AND
Localitate = ""))
Nici această formă nu funcționează în VFP. În general, ștergerea unor linii trebuie privită cu multă circumspecție, deoarece atunci când linia de șters conține valori ale unor atribute ce apar în alte tabele ca și chei străine, există riscul pierderii integrității referențiale.
Standardul SQL92 (nu și dialectul SQL din VFP) permite la crearea unei tabele descrierea acțiunii care se va derula la ștergerea unei linii părinte în cazul în care există linii-copil. Spre exemplu, se poate refuza ștergerea de linii din tabela CLIENȚI, dacă la crearea tabelei FACTURIEMISE se specifică:
CREATE TABLE FACTURIEMISE
(NrFactura DECIMAL(8) NOT NULL,
DataFactura DATE,
CodClient DECIMAL(6) NOT NULL,
ValoareTotala DECIMAL(15) not NULL,
TVAColectata DECIMAL(14) ,
PRIMARY KEY (NrFactura),
FOREIGN KEY (CodClient) REFERENCES CLIENTI
ON DELETE RESTRICT)
Modificarea valorilor unor atribute
Pentru modificarea valorilor unuia sau multor atribute dintr-o tabelă, comanda utilizată este UPDATE care are formatul general:
UPDATE tabelă
SET atribut = expresie
WHERE predicat
Ca rezultat, vor fi modificate valorile atributului specificat, noile valori ale acestuia fiind cele care rezultă în urma evaluării expresiei; modificarea se va produce pe toate liniile tabelei care îndeplinesc condiția specificată în predicat.
Exemplu 4
În tabela CLIENȚI, fiecărui client i-a fost atribuit un cod unic, începând cu 1001. Dacă din diferite motive, se dorește ca "numerotarea" clienților să înceapă de la 3001, păstrându-se ordinea, se poate articula fraza UPDATE următoare:
UPDATE CLIENȚI
SET CodClient = CodClient + 2000
Exemplul este suficient de neinspirat, deoarece în practică modificarea codului clienților antrenează modificarea valorilor acestui atribut în toate tabelele în care apare (în cazul nostru FACTURIEMISE), datorită faptului că este o cheie străină.
3.4.6. Aplicații rezolvate
Se consideră o aplicație de gestiune economică care rulează într-o entitate economică. Baza de date (gest_ec) conține următoarele tabele:
PRODUSE
PRETURI
COMENZI
DEPOZITE
SALARIATI
CLIENȚI
1. Să se creeze tabelele
CREATE TABLE PRODUSE (CODD INTEGER NOT NULL, CODP INTEGER NOT NULL, DENP VARCHAR(50) NOT NULL, STOC DOUBLE(10,3), DATACRT DATE, UM VARCHAR(3), PRIMARY KEY (CODD,CODP), FOREIGN KEY (CODD) REFERENCES DEPOZITE(CODD), FOREIGN KEY (CODP) REFERENCES PRETURI(CODP) );
CREATE TABLE PRETURI (CODP INTEGER NOT NULL PRIMARY KEY, PRETMAX DOUBLE(10,2) NOT NULL, PRETMIN DOUBLE(10,2) NOT NULL, DATAI DATE NOT NULL, DATASF DATE NOT NULL, FOREIGN KEY (CODP) REFERENCES COMENZI(CODP));
CREATE TABLE COMENZI (NRCOM INTEGER NOT NULL, CODP INTEGER NOT NULL, CODC INTEGER NOT NULL, DATAL DATE, CANT DOUBLE(10,3) NOT NULL, PRET DOUBLE(10,2) NOT NULL, FOREIGN KEY (CODC) REFERENCES CLIENTI(CODC));
CREATE TABLE DEPOZITE (CODD INTEGER NOT NULL PRIMARY KEZ, DEND VARCHAR(50) NOT NULL, NRSAL INTEGER NOT NULL , DATACRT DATE, UM VARCHAR(3), FOREIGN KEY (CODD) REFERENCES SALARIATI(CODD));
CREATE TABLE SALARIATI (MARCA INTEGER NOT NULL PRIMARY KEY, NUME VARCHAR(50) NOT NULL, FUNCT VARCHAR(20), CODD INTEGER NOT NULL, SALA INTEGER NOT NULL, CODS INTEGER NOT NULL);
CREATE TABLE CLIENTI (CODC INTEGER NOT NULL PRIMARY KEY , DENC VARCHAR(50) NOT NULL, CODFISCAL VARCHAR(20) NOT NULL, REGCOM VARCHAR(20) NOT NULL, ADRESA VARCHAR(50) NOT NULL, TELEFON VARCHAR(20) NOT NULL, SOLD DOUBLE(10,2));
2. sa se insereze in tabela SALARIATI urmatoarele inregistrari
Insert into salariati set marca=1111,nume=”AVRAM ION”,funct=”vanzator”, codd=100000, sala=21200, vens=1000, cods=1000; sau
Insert into salariati value (1111,”AVRAM ION”,”vanzator”,100000,21200,1000,1000);
3. Să se selecteze toate coloanele din tabela SALARIATI.
SELECT * FROM SALARIATI;
4. Sa se selecteze coloanele MARCA,NUME,SALA,VENS din tabela SALARIATI;
Select marca,nume,sala,vens from SALARIATI ;
5. Sa se selecteze NUME din tabela SALARIATI
SELECT NUME FROM SALARIATI ;
6. Sa se selecteze coloana FUNCT din tabela SALARIATI in variantele utilizarii si neutilizarii clauzei distinct.
A. SELECT FUNCT FROM SALARIATI ;
B. SELECT DISTINCT FUNCT FROM SALARIATI;
7. Sa se selecteze toate inregistrarile privind salariatii al caror salariu este mai mare de 15000 lei.
SELECT * FROM SALARIATI WHERE SALA>15000 ;
9. sa se selecteze coloanele MARCA,NUME si veniturile totale (SALA+VENS) pentru angajatii care au un salariu mai mare ca 35000 lei.
SELECT MARCA,NUME, SALA+VENS FROM SALARIATI WHERE SALA>35000 ;
10. Sa se selecteze coloanele NUMA si FUNCT pentru salariatii care au functia de vanzator.
Select nume,funct from salariati where funct= »vanzator »
11. Sa se selecteze coloanele MARCA,NUME, CODD din tabela SALARIATI, daca venitul este mai mare decat salariul.
Select MARCA,NUME,CODD from SALARIATI where vens>sala ;
12. sa se selecteze si afiseze campurile MARCA,NUME, SALARIU pentru salariatii ale caror venituri suplimentare sunt mai mari ca 1500 lei si lucreaza in subordinea superiorului cu codul 1000.
Select MARCA,NUME,SALA from salariati where vens>1500 and cods=1000 ;
13. sa se afiseze toate coloanele pentru salariatii cu functia vanzator, care au salariul mai mare ca 20000 lei si lucreaza in subordinea superiorului cu codul 1000.
Select * from SALARIATI where sala>20000 and cods=1000 ;
14. sa se afiseze coloana NUME pentru angajatii care au salariul mai mic ca 21000 lei.
Select NUME from salariati where sala < 21000 ;
15. sa se selecteze inregistrarile pentru care functia este “SEF DEP” sau salariul este mai mare ca 35000 lei.
Select * from salariati where funct = « SEF DEP » or sala>35000 ;
16. sa se selecteze inregistrarile pentru care functia este “vanzator” si nu lucreaza in sbordinea superiorului cu codul 1000.
Select * from salariati where funct = « vanzator » and cods!=1000 ;
17. sa se selecteze toti salariatii care lucreaza in subordinea superiorului cu codul 1000 , precum si cei care au salariul mai mic de 30000 lei sau functia de vanzator.
Select * from salariati where funct= »vanzator » or sala <30000 and cods=1000 ;
18. sa se selecteze toate inregistrarile care contin date despre angajatii a caror functie este cea de sef de deposit sau care au un salariu de 35000 lei si lucreaza in subordinea superiorului cu codul 1000.
Select * from salariati where funct= »sef dep » or (sala=35000 and cods=1000);
19. sa se selecteze marca si numele salariatilor care lucreaza in subordinea superiorului cu marca 1000 si care au functia de sef de deposit sau sau salariul in valoare de 35000 lei.
Select * from salariati where (funct= »sef dep » or sala=35000) and cods=1000 ;
20. sa se afiseze valorile coloanelor marca, nume, funct privind angajatii care lucreaza in subordinea superiorului cu marca 1000 si au functia de sef de deposit sau vanzator.
Select * from salariati where (funct= »sef dep » or funct= »vanzator ») and cods=1000 ;
21. sa se selecteze MARCA,NUME, FUNCT pentru salariatii care au functia de sef de deposit sau pentru cei care lucreaza in subordinea superiorului cu marca 1000 si au functia de vanzator.
Select * from salariati where funct= »sef dep » or (funct= »vanzator » and cods=1000) ;
23. sa se selecteze toti angajatii din tabela SALARIATI care nu au functia de vanzator.
Select * from SALARIATI where not(funct=’vanzator’) ;
24. sa se selecteze valorile coloanelor MARCA,NUME, FUNCT,SALA+VENS pentru angajatii care au salariul cuprins intre 24500 si 36000.
Select MARCA,NUME,FUNCT,SALA+VENS from SALARIATI where sala between 24500 and 36000 ;
25. sa se selecteze campurile MARCA,NUME, FUNCT,SALA+VENS pentru angajatii care au salariul mai mic decat 24500 si mai mare decat 36000.
Select MARCA,NUME,FUNCT,SALA+VENS from SALARIATI where sala not between 24500 and 36000 ;
26. sa se selecteze campurile MARCA,NUME, FUNCT,SALA+VENS pentru angajatii care lucreaza in depozitul cu codurile 100000 sau 160000
Select MARCA,NUME,FUNCT,SALA+VENS from SALARIATI where codd in (100000,160000);
27. sa se selecteze campurile MARCA,NUME, FUNCT,SALA+VENS pentru angajatii care au alta functie decat cea de vanzator.
Select MARCA,NUME,FUNCT,SALA+VENS from SALARIATI where funct not in (‘vanzator’);
28. sa se selecteze campurile NUME,MARCA,FUNCT si veniturile suplimentare pentru angajatii al caror nume incepe cu litera C
Select MARCA,NUME,FUNCT, VENS from SALARIATI where nume like “C%”;
29. sa se selecteze campurile MARCA,NUME, FUNCT,SALA+VENS pentru angajatii al caror nume se termina cu litera N.
Select MARCA,NUME,FUNCT,SALA+VENS from SALARIATI where nume like “%N”;
30. sa se selecteze campurile MARCA,NUME, FUNCT,SALA+VENS pentru angajatii al caror nume este format din noua caractere, pe ultima pozitie fiind N.
Select MARCA,NUME,FUNCT,SALA+VENS from SALARIATI where nume like “________N”;
31. sa se selecteze angajatii al caror nume are pe pozitia a treia litera M.
Select MARCA,NUME,FUNCT,SALA+VENS from SALARIATI where nume like “__M%”;
32. 30. sa se selecteze campurile MARCA,NUME, FUNCT,SALA+VENS pentru angajatii al caror nume este format din noua caractere.
Select MARCA,NUME,FUNCT,SALA+VENS from SALARIATI where nume like “_________”;
33. Sa se selecteze salariatii care nu venit suplimentar.
Select * from salariati where vens is null ;
3.4.7. Probleme propuse
1.Sa se afiseze codul produsului, data de sfirsit si a unui nou termen de valabilitate a unui pret dat,
calculat prin adaugarea a trei luni. Sa se selecteze doar produsele al caror cod este mai mic decit 13333 si data de sfirsit este mai mare decit data curenta plus trei luni.
2.Sa se afiseze numele, marca, raportul VENS/SALA si veniturile totale pentru sefii de depozite. Ordonarea datelor sa fie facuta crescator dupa valorile raportului mentionat.
3. Sa se afiseze media anuala a veniturilor totale (SALA+VENS) pentru salariatii cu functia 'VINZATO'.
4. Sa se selecteze codul produsului, data de sfarsit, data curenta, valorile expresiilor TRUNC(DATSF+90)-TRUNC(SYSDATE) si DATASF+90. Selectia sa se realizeze pentru produsele cu codul mai mare ca13333 si data de sfirsit plus 90 de zile mai mare decit data curenta.
5. Sa se selecteze salariatii al caror nume are o lungime de noua caractere.
6. La selecteze coloanele CODP, DATASF la produsele cu codul mai mare ca 13333, afisand primele trei litere de la zi, luna in litere si anul cu patru cifre.
7. Sa se selecteze marca si numele salariatilor care lucreaza in subordinea superiorului cu marca 1000 si au functia sef de depozit sau salariul in valoare de 3500000 de lei.
8. Din tabela COMENZI (definita prin etichetele T1 si T2) sa se selecteze CODP, CODC, in conditiile in care valoarea comenzii este mai mare ca 500000 lei. (JOIN -ul unei tabele pe ea insasi).
9. Sa se selecteze coloanele NUME, MARCA, VENS, SALA+VENS din tabela SALARIATI, in conditiile in care codul superiorului este 1000.
10. Sa se afiseze cimpurile CODP, DENP, STOC si CANT, utilizand criteriul egalitatii OUTER-JOIN, pe campul comun CODP (se afiseaza datele despre datele despre acele produse pentru care exista comenzi dar nu sunt in nomenclatorul de produse). Liniile sa fie ordonate crescator dupa campul CODP.
11.Sa se afiseze numele si marca acelor angajati al caror nume se pronunta asemanator cu DORU DAN.
12. Sa se selecteze campurile NUME si FUNCT ale salariatilor cu functia identica cu a lui RADU IOANA.
13. Sa se selecteze codul produsului, data maxima admisa de practicare a unui pret si data curenta pentru acele produse care indeplinesc conditia ca DATASF+10 sa fie mai mare decit SYSDATE,
14. Sa se selecteze cimpurile MARCA, NUME, SALA, VENS pentru salariatii care au alta functie decat cea de vanzator.
15. Sa se selecteze crescator dupa salariu, angajatii cu functia vinzator, si pentru care marca superiorului este 1000.
16. Sa se selecteze si afiseze valoarea medie zilnica a comenzilor ce trebuie onorate in perioada 01-03 Iulie 2005.
17. Sa se afiseze primele 5 carcatere din nume, marca si primul carcater din functie, pentru toti angajatii.
18. Sa se afiseze o situatie finala prin care sa fie redate cimpurile NUME si MARCA angajatului reunite
intr-un camp comun, denumit "INFORMATIE" si cimpul venituri totale anuale denumit VENIT_ANUAL.
Selectia este ceruta pentru angajatii cu codul superiorului egal cu 1000.
19. Sa se selecteze campurile NUME si CODD ale angajatilor cu codul superiorului 1000 si care au
aceeasi functie cu DORU DAN. Sa se afiseze numai salariatii pentru care exista corespondenta de
CODD in tabelele DEPOZITE si SALARIATI. Datele sa fie ordonate crescator dupa valorile CODD si NUME.
20.Sa se selecteze cimpurile CODP, DENP, PRET, PRETMAX, PRETMIN pentru produsele al caror pret negociat este cuprins intre pretul maxim si pretul minim. Ordonarea sa se faca crescator dupa campul CODP.
21. Din tabela COMENZI (definita prin etichetele T1 si T2) sa se selecteze CODP, CODC, in conditiile in care valoarea comenzii este mai mare ca 500000 lei. (JOIN -ul unei tabele pe ea insasi).
22. Sa se afiseze toate coloanele pentru salariatii cu functia vanzator, care au salariul mai mare ca 3500000 lei si lucreaza in subordinea superiorului cu codul 1000.
23. Sa se selecteze coloanele CODP, DATASF la produsele cu codul mai mare ca 13333, afisind ziua si luna in litere iar anul cu patru cifre.
24. Sa se selecteze coloanele MARCA, NUME, CODD, VENS ordonate crescator dupa codul depozitului si veniturile suplimentare.
25. Sa se selecteze toate coloanele din tabela SALARIATI.
26.Sa se afiseze valoarea totala a salariilor si veniturilor suplimentare pentru salariatii cu functia 'VINZATO'.
27. Sa se selecteze salariatii al caror nume are o lungime de noua caractere.
28. se selecteze coloanele MARCA, NUME, CODD din tabela SALARIATI, daca venitul suplimentar este mai mare decat salariul.
29. Sa se selecteze din tabela PRETURI valorile cimpului CODP si DATASF. Data de sfirsit (DATASF) sa se prezinte insotita de timpul intern, exprimat in diverse forme de afisare.
30. Sa se afiseze numarul de valori nenule inregistrate in coloana VENS din tabela SALARIATI.
Referinte bibliogafice
Moraru, S., Perniu, L. – Web-applications on databases in electrical domain, Ed. Lux Libris, 2004.
Connolly, T., Begg, C., Strachan, A. – Baze de date, Ed. Teora, 2000.
Connolly, T., Begg, C., Strachan, A. – Database Systems – A Practical Approach to Design, Implementation and Management, Addison Wesley Longman Limited 1995, 1998
Florescu, V. and co. – Databases. Practical and Teoretical Approach, Infomega, 2001
Velicanu, M., Lungu, , Bodea C., Ioniță, C., Bădescu G. – Database Management Systems, Editura Petrion, 2000
Popescu, I. – Database Design, Editura Tehnică, 2001
Sabău G., Avram V. – Computer Systems and Databases, Editura Oscar Print
Henderson, K. – The Guru‘s Guide to Transact-SQL, Addison Wesley, 2000
Waymire, R., Sawtell, R. – Sams Teach Zourself Microsoft SQL Server 2000 in 21 Days, Sams Publishing, 2001
Henderson, K. – The Guru‘s Guide to SQL Server Stored Procedures, XML, and HTML Addison Weslwey, 2002
Reingruber, M. C., Gregory W. – The Data Modeling Handbook, John Wiley & Sons, 1994.
Martin J. – An end users guide to Data Base, Prentice Hall, 1981
Carter J. – The relational database, Chapman & Hall, 1995
Fleming, von Halle, – The Handbook of RelationalDatabase Design, Addison-Wesley.
Chen, P. P. – The entity-relationship model: toward a unified view of data, ACM Trans. on Database Systems, 1976.
Batini, C., S. Ceri, S. B. Navathe, C. Batini – Conceptual Database Design: an Entity/Relationship Approach, Addison-Wesley, , 1991.
R. Jennings, P. Hipson – Database Developer's Guide with Visual C++ 4, Second Edition, Sams Publishing, 1996
Date, C.J. – An Introduction to Database Systems (5th ed.). CA: Addison-Wesley, 1991.
Date, C.J. – An Introduction to Database Systems (7th ed.). CA: Addison-Wesley, 2000.
Elmasri, R., Navathe, S.B. – Fundamentals of Database Systems (3rd ed.). CA: Addison-Wesley, 2000.
Johnson, J.L. – Database: Model, Languages, Design. NY: Press, 1997.
Robson, W. – Strategic Management & Information Systems (2nd ed). Pitman, 1997.
Avery, B. – The Relational Model, , [PDF document] URL http://www.kingston.ac.uk/~ku12492/MBIT/model.pdf.
Brown, C.E. – The Relational Model, Database learning module, http://www2.bus.orst.edu/faculty/brownc/lectures/db_tutor/relational_model.htm#3.1%20Rela-tional%20Data%20Model%20Concepts.
Bull, M. – Codd’s Rules for RDBMS, MB-online publication. , 2002, URL http://hometown.aol.com/mbaddenda/art120.html.
Parkhurst, T. – Codd’s 12 rules. DATA MANAGEMENT STRATEGIES, http://www.itworld.com/nl/db_mgr/09022002/pf_index.html, 2002, Feb. 9.
Rennhackkamp, M. – Relational Integrity Control, DBMS online Server side. http://www.dbmsmag.com/9606d17.html, 1996 June.
Webopedia, – Referential Integrity, http://www.webopedia.com/TERM/r/referential_integrity.html.
Codd, E. – "Is Your DBMS Really Relational?" and "Does Your DBMS Run By the Rules?" ComputerWorld, October 14 and October 21, 1985.
Hernandez J. M. – Database Design for Mere Mortals, Addison Wesley, 1996
Davies, C.T., – Recovery Semantics for a DB/DC System, In Proc. ACM Annual Conference, 1973.
Eswaran, K.P., Gray, J.N., Lorie, R.A., Traiger, I.L. – The Notions of Consistency and Predicate Locks in a Database System, CACM 19,11, 1976
Scheuerl, S, J.G. – Modelling Recovery in Database Systems, School of Mathematical and Computational of , 1997
Yovits, M. C. – Advances in Computers, Vol. 38. (Ed.), Academic Press, 1994.
Hernandez, M. J. – Database design for mere mortals : a hands-on guide to relational database design, 2nd ed., Addison Wesley, 2003.
Referinte bibliogafice
Moraru, S., Perniu, L. – Web-applications on databases in electrical domain, Ed. Lux Libris, 2004.
Connolly, T., Begg, C., Strachan, A. – Baze de date, Ed. Teora, 2000.
Connolly, T., Begg, C., Strachan, A. – Database Systems – A Practical Approach to Design, Implementation and Management, Addison Wesley Longman Limited 1995, 1998
Florescu, V. and co. – Databases. Practical and Teoretical Approach, Infomega, 2001
Velicanu, M., Lungu, , Bodea C., Ioniță, C., Bădescu G. – Database Management Systems, Editura Petrion, 2000
Popescu, I. – Database Design, Editura Tehnică, 2001
Sabău G., Avram V. – Computer Systems and Databases, Editura Oscar Print
Henderson, K. – The Guru‘s Guide to Transact-SQL, Addison Wesley, 2000
Waymire, R., Sawtell, R. – Sams Teach Zourself Microsoft SQL Server 2000 in 21 Days, Sams Publishing, 2001
Henderson, K. – The Guru‘s Guide to SQL Server Stored Procedures, XML, and HTML Addison Weslwey, 2002
Reingruber, M. C., Gregory W. – The Data Modeling Handbook, John Wiley & Sons, 1994.
Martin J. – An end users guide to Data Base, Prentice Hall, 1981
Carter J. – The relational database, Chapman & Hall, 1995
Fleming, von Halle, – The Handbook of RelationalDatabase Design, Addison-Wesley.
Chen, P. P. – The entity-relationship model: toward a unified view of data, ACM Trans. on Database Systems, 1976.
Batini, C., S. Ceri, S. B. Navathe, C. Batini – Conceptual Database Design: an Entity/Relationship Approach, Addison-Wesley, , 1991.
R. Jennings, P. Hipson – Database Developer's Guide with Visual C++ 4, Second Edition, Sams Publishing, 1996
Date, C.J. – An Introduction to Database Systems (5th ed.). CA: Addison-Wesley, 1991.
Date, C.J. – An Introduction to Database Systems (7th ed.). CA: Addison-Wesley, 2000.
Elmasri, R., Navathe, S.B. – Fundamentals of Database Systems (3rd ed.). CA: Addison-Wesley, 2000.
Johnson, J.L. – Database: Model, Languages, Design. NY: Press, 1997.
Robson, W. – Strategic Management & Information Systems (2nd ed). Pitman, 1997.
Avery, B. – The Relational Model, , [PDF document] URL http://www.kingston.ac.uk/~ku12492/MBIT/model.pdf.
Brown, C.E. – The Relational Model, Database learning module, http://www2.bus.orst.edu/faculty/brownc/lectures/db_tutor/relational_model.htm#3.1%20Rela-tional%20Data%20Model%20Concepts.
Bull, M. – Codd’s Rules for RDBMS, MB-online publication. , 2002, URL http://hometown.aol.com/mbaddenda/art120.html.
Parkhurst, T. – Codd’s 12 rules. DATA MANAGEMENT STRATEGIES, http://www.itworld.com/nl/db_mgr/09022002/pf_index.html, 2002, Feb. 9.
Rennhackkamp, M. – Relational Integrity Control, DBMS online Server side. http://www.dbmsmag.com/9606d17.html, 1996 June.
Webopedia, – Referential Integrity, http://www.webopedia.com/TERM/r/referential_integrity.html.
Codd, E. – "Is Your DBMS Really Relational?" and "Does Your DBMS Run By the Rules?" ComputerWorld, October 14 and October 21, 1985.
Hernandez J. M. – Database Design for Mere Mortals, Addison Wesley, 1996
Davies, C.T., – Recovery Semantics for a DB/DC System, In Proc. ACM Annual Conference, 1973.
Eswaran, K.P., Gray, J.N., Lorie, R.A., Traiger, I.L. – The Notions of Consistency and Predicate Locks in a Database System, CACM 19,11, 1976
Scheuerl, S, J.G. – Modelling Recovery in Database Systems, School of Mathematical and Computational of , 1997
Yovits, M. C. – Advances in Computers, Vol. 38. (Ed.), Academic Press, 1994.
Hernandez, M. J. – Database design for mere mortals : a hands-on guide to relational database design, 2nd ed., Addison Wesley, 2003.
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: Limbaje de Definire Si Manipulare a Datelor (ID: 149970)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
