Documente Academic
Documente Profesional
Documente Cultură
Caracteristici Esentiale Ale SGBD Si SGBC
Caracteristici Esentiale Ale SGBD Si SGBC
1
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
CUPRINS
4
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
SGBD sunt azi oferite pe o mare varietate de platforme de calcul, pornind de la calculatoarele
personale (PC) şi până la sistemele de procesare paralelă masivă a datelor, sub medii extrem de
diverse, incluzând DOS, Windows, Novell Netware, Macintosh, Unix, OS/2, VMS, OS/400, MVS.
Majoritatea liderilor mondiali din industria de programare oferă cel puţin un SGBD, dacă nu mai multe;
dintre aceştia, este suficient să amintim IBM, Computer Associates, Sybase Inc., Oracle, Microsoft,
Borland.
Marile corporaţii ale lumii, ca şi foarte multe dintre cele medii sau mici, depind de peste două
decenii de SGBD, cărora le sunt încredinţate funcţiuni critice în afaceri, precum urmărirea vânzărilor,
cheltuielilor, stocurilor, încasărilor sau plata salariilor. Dar şi foarte mulţi oameni fac apel la SGBD pentru
uzul personal, fie că este vorba de monitorizarea investiţiilor familiale, fie de bd gestionând biblioteca
proprie de cărţi, reviste, fotografii, diapozitive, casete audio, video, discuri şi CD-ROM-uri audio, video
sau de date etc. Industria de SGBD genera în 1994 venituri depăşind 5 miliarde de dolari anual în lume,
cifră mereu în creştere!
Tranzacţii
Orice SGBD trebuie să asigure, în primul rând, un limbaj de definire şi manipulare a
datelor, conform modelului de date suportat. Prin intermediul acestuia, se oferă utilizatorilor, în esenţă,
posibilitatea de a memora datele structurate în bd şi de a le accesa (pentru interogări şi/sau actualizări).
Pentru a asigura partajarea datelor în medii multi-utilizator, SGBD trebuie să ofere mecanisme de
grupare a tuturor operaţiilor care concură la îndeplinirea unei “sarcini logice unitare” într-o singură
tranzacţie, astfel încât SGBD să poată garanta ori că execuţia unei tranzacţii a avut loc complet, fără a fi
afectată de alte tranzacţii, ori că tranzacţia nu a fost deloc executată (bd nefiind deci afectată de
tranzacţie).
Tranzacţiile sunt, prin urmare, singurele “instrucţiuni logice atomice” oferite de un SGBD; ca
atare, ele ori se execută integral, ori deloc, în nici un caz parţial, dpdv al oricărei alte tranzacţii. Altfel
spus, orice tranzacţie parţial executată (de exemplu, din cauza unei căderi de tensiune) trebuie abortată,
iar toate efectele ei trebuie ignorate (“rolled back”). În caz contrar, în mod evident, ar putea rezulta stări
inconsistente ale bd.
Exemplul 9.1
dintre angajaţii mutaţi ar putea avea salariile mărite înainte de mutare iar alţii nu!
Pentru păstrarea consistenţei datelor, ori tranzacţia de mărire salarii a fost lansată
prima iar cea de mutare angajaţi trebuie lansată după terminarea tuturor măririlor
de salarii (cu efectul că toţi angajaţii mutaţi vor avea salariile mărite), ori, invers,
tranzacţia de mutare angajaţi a fost lansată prima iar cea de mărire salarii trebuie
lansată abia după încheierea tuturor mutărilor (cu efectul că nici unul dintre
angajaţii mutaţi nu va avea salariul mărit).
Literatura de specialitate se referă, în acest sens, la cele patru proprietăţi ACIDe ale
tranzacţiilor:
De remarcat însă că, pe lângă toate aceste probleme “clasice” ce apar în implementarea
SGBD, ca în mai toate domeniile (poate doar cu o viteză mult mai mare) şi această industrie trebuie
permanent să se adapteze atât la noile cerinţe ale utilizatorilor, cât şi la avansurile tehnologice hard şi
soft. Considerăm că cele mai semnificative tendinţe ce se manifestă azi în industria SGBD sunt
următoarele:
Deşi toate acestea depăşesc cadrul fixat pentru prezenta lucrare, considerăm totuşi utilă
măcar o trecere sumară în revistă a lor în continuarea acestui capitol introductiv al ultimei părţi.
• off-line (batch, bazate pe job-uri procesate ulterior), rulau pe platforme mari (mainframe,
tipic IBM, sub OS, SIRIS sau MVS), folosind cartele perforate, în regim uniutilizator, uniproces;
programele nu se executau în timp real, ci erau procesate ulterior, pe baza unui sistem de
priorităţi. Acest tip de SGBD primitiv mai este încă folosit şi azi în lume, nu doar din
6
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
• on-line (asistenţă decizii, procesare tranzacţii în timp real), rulau pe platforme mini (tipic
DEC, sub RSX, VMS sau Unix), oferind acces multiutilizator, multiproces, de la mai multe
terminale conectate la sistemul de calcul. Acest tip de SGBD este încă majoritar în lume, fiind
în continuare folosit de mai toate marile corporaţii, de la bănci la uzine, tendinţa fiind însă de
evoluţie spre arhitecturi deschise, client / server.
Apariţia PC-urilor, foarte ieftine şi exploziv mai performante an după an, oferind afişaj în culori,
o grafică net superioară, icoane, mouse şi lucru în ferestre accesibile nu doar programatorilor de
calculatoare, a avut rapid un impact uriaş şi asupra industriei SGBD, ducând în foarte multe companii
(mai ales mici şi mijlocii) la desfiinţarea departamentelor informatice, la descentralizarea totală a
procesării datelor şi la angrenarea nespecialiştilor în programare în preluarea controlului direct asupra
gestiunii datelor. Acestui pionierat în domeniu, întâi sub CP/M, apoi DOS şi Windows, i-au corespuns
SGBD-uri de tip dBase.
Foarte repede şi nu doar din dorinţa de a utiliza în comun periferice scumpe (discuri hard de
mare capacitate, imprimante laser, scanner, CD-ROM etc.) sau de a comunica între PC-uri prin mesaje
şi poştă electronică, ci mai ales pentru integrarea bd, eliminarea redundanţelor şi accesul partajat la
date, PC-urile au fost interconectate întâi în reţele locale de calculatoare (LAN) şi apoi în reţele
regionale (WAN). În special sub Novell Netware, apoi şi sub Windows NT, Windows ’95, SunSoft
sau Banyan, piaţa de SGBD corespunzătoare a fost şi este încă dominată de FoxPro, Access şi
Paradox. Acestea pot fi configurate atât pentru lucru local, individual, pe un singur PC neconectat în
reţea, cât şi pentru lucrul în reţea.
Tipic, în acest din urmă caz, unul sau mai multe calculatoare din reţea sunt configurate ca
server, iniţial dedicat (de date şi/sau de imprimare) iar celelalte drept, clienţi cuplaţi iniţial, la un
moment dat, la un singur server de date şi eventual la unul de imprimare. Ulterior, aceste arhitecturi
arborescente iniţiale au fost înlocuite cu arhitecturi mai flexibile (“punct la punct”) în care orice PC poate
fi cuplat simultan la orice alt PC, căci fiecare PC poate fi configurat atât server cât şi client.
Necesitatea de a factoriza datele comune ale unei companii şi de a asigura accesul rapid la
ele, în condiţiile în care volumul şi structura acestora sunt foarte mari, a condus la apariţia de servere
SGBD, în general rulând pe un PC foarte puternic sau, mai ales, pe minicalculatoare, la care sunt
cuplate clienţi PC într-o arhitectură client / server. La un asemenea server (Oracle, Sybase, DB/2,
OpenIngres, MS SQL Server etc.), oferind tipic bd relaţionale accesabile în SQL (“Structured Query
Language”, “Limbaj Structurat de Interogare”) sunt cuplabile LAN-uri heterogene din punct de vedere
al sistemului de operare în reţea şi SGBD utilizat (de la Paradox 3.5 sub Novell, la Internet Explorer
sub Windows’95!).
Principalele probleme de implementare relative la arhitecturile client / server sunt legate de:
7
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
Aceste realităţi obligă furnizorii de SGBD să asigure portabilitatea lor pe (sau variante
dedicate pentru) platforme de calcul multiple, precum şi interoperabilitatea între produsele proprii şi
cele similare ale concurenţilor. Asemenea sisteme deschise gestionează în mod natural baze de date
distribuite (bdD) şi necesită diverse forme de interfeţe de acces.
• în bd distribuite sunt interconectate în reţea doar SGBD server (fiecare dintre ele putând sau
nu avea conectaţi clienţi proprii); serverele SGBD interconectate cooperează între ele pentru
gestiunea în comun a datelor, pentru accesul utilizatorilor locali la acestea, ca şi pentru toate
celelalte funcţiuni SGBD abordate în următoarele capitole;
• cea de-a doua diferenţă este legată de faptul că arhitecturile distribuite sunt concepute pentru
a suporta bd globale, integrate, deşi memorarea datelor şi procesarea lor poate fi răspândită
pe o arie geografică largă şi, mai mult, tabelele bd pot fi partiţionate (vertical, pe coloane şi/sau
orizontal, pe linii) între servere.
Mai mult, pentru procesarea tranzacţiilor, o bd distribuită poate folosi simultan oricâte dintre
serverele de SGBD disponibile pentru a optimiza performanţele execuţiei acestora folosind procesarea
paralelă. Dual însă, bd distribuite se bazează şi pe autonomia locală a fiecărui server SGBD
component. Aceste sisteme sunt proiectate astfel încât administratorii locali de bd păstrează controlul
asupra bd locale corespunzătoare, stabilind inclusiv asupra căror porţiuni de date oferă acces (şi cu ce
privilegii) utilizatorilor locali ai altor servere. În plus, nici un server local nu depinde de vreun alt server
pentru gestionarea şi accesul la datele proprii, permiţând exploatarea lor chiar dacă vreun alt server nu
este temporar în serviciu sau dacă, din cauza unei căderi a reţelei de comunicaţii interservere, vreun nod
local rămâne complet izolat de celelalte servere pentru o perioadă de timp.
Din punctul de vedere al utilizatorilor însă şi, în special, al programatorilor, cea mai importantă
caracteristică a noilor bd distribuite este transparenţa localizării, adică obţinerea independenţei
aplicaţiilor faţă de localizarea la un moment dat a datelor. În această abordare a bd distribuite, numită şi
“imaginea unui singur sit” (“single-site image”), distribuirea datelor este complet transparentă
utilizatorilor; ca atare, de exemplu, se pot muta date de pe un server pe altul fără ca utilizatorii să
trebuiască să ştie acest lucru sau să fie în vreun fel afectaţi.
8
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
Principalul mecanism prin care este implementată transparenţa localizării este includerea în
numele global (“systemwide name”) al oricărui obiect aflat în gestiunea bd distribuite a “locului
naşterii” obiectului, deci a locaţiei unde a fost creat iniţial, şi menţinerea informaţiilor despre obiect, pe
toată durata existenţei sale, de către SGBD al locului său de naştere. Dacă un obiect este mutat la o altă
locaţie, el este “luat în evidenţă” şi de SGBD al noii locaţii (şi “scos din evidenţa” locului de unde s-a
mutat, dacă acesta nu este locul său de naştere, întocmai cum procedează Birourile de evidenţa
populaţiei sau Comisariatele militare!), dar SGBD de la locul naşterii memorează automat un pointer
către noua locaţie a obiectului (sau îl modifică pe cel vechi).
În fine, bd distribuite permit natural creşterea incrementală prin adăugarea de noi noduri pe
măsură ce cerinţele o impun. De cele mai multe ori, această soluţie este, de departe, mult mai bună
decât upgrade-ul vreunui server existent (ce nu ar putea să nu perturbe măcar o vreme utilizatorii locali
ai acelui nod).
Porţile de acces sunt strămoşii interfeţelor de acces; aceste programe, de tip control
(“software driver”), asigură conectivitatea (în general limitată) între două sisteme de programe de tipuri
precis definite (dar nu neapărat diferite! vezi, de exemplu, Novell Netware). Ele sunt în continuare
folosite ori de câte ori nu există (sau ar fi prea scump încă apelul la) interfeţe de acces adecvate.
• costul mai redus, la aceeaşi putere de calcul oferită, în raport cu calculatoarele cu un singur
procesor foarte puternic
• potenţialul de scalabilitate inclus (clienţii pot achiziţiona întâi unul sau doar două procesoare,
urmând ca restul să poată fi achiziţionate ulterior, pe măsura necesităţilor)
• posibilitatea procesării paralele, crucială în mărirea performanţelor oricărui SGBD gestionând
volume mari de date complex structurate.
Procesarea paralelă este un domeniu extrem de promiţător, deşi momentan nu există prea
multe SGBD-uri comerciale capabile de aşa ceva. În special bd logice şi relaţionale ar putea profita din
plin de procesarea paralelă, în special în cazul volumelor mari de date, deoarece atât expresiile logice
sau de algebră relaţională, cât şi colecţiile de tabele (şi chiar tabelele) pot fi partiţionate “canonic” iar
fiecare dintre părţile astfel rezultate pot fi încredinţate câte unui procesor pentru execuţie simultană.
În special bd multimedia (pentru care deja doi producători americani de aplicaţii “video la
cerere” au adoptat procesarea paralelă!), care presupun gestiunea şi accesul unor date având
dimensiuni extrem de mari, dar şi bd uzuale în care concurenţa tranzacţiilor este foarte mare ar avea
nevoie stringentă de SGBD bazate pe procesare paralelă.
9
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
• nimic partajat;
• discuri partajate;
• memorie partajată (prin intermediul căreia şi discurile sunt partajate!).
Principalul dezavantaj este însă acela că, software, încărcarea echilibrată a procesoarelor
este foarte greu de realizat (mai ales atunci când tranzacţiile accesează des multe date comune, ceea
ce are ca efect imposibilitatea unei partiţionări simetrice a datelor şi, deci, supraîncărcarea unui procesor
şi nefolosirea celorlalte la puterea lor). În plus, la orice adăugare a unui nou procesor datele trebuie
repartiţionate, iar sistemul de operare trebuie să suporte un trafic de mesaje greu pentru unica
comunicaţie posibilă, cea interprocesoare. De asemenea, căderea unui procesor sau a memoriei sale au
ca efect pierderea posibilităţii de a mai accesa datele de pe discurile acestuia. Ca remediu, unele
platforme oferă salvări interdiscuri precum şi procesoare şi memorii redundante, de rezervă.
Deoarece este oricând posibil ca două sau mai multe procesoare să acceseze simultan
aceleaşi date de pe disc, pentru a păstra integritatea bd este nevoie de un mecanism global de blocare;
acesta este numit gestionarul de blocări distribuit şi e folosit în două scopuri:
• pentru punerea şi scoaterea lacătelor (vezi capitolul următor) în funcţie de starea tranzacţiilor
executate pe procesoarele concurând la aceleaşi date; şi
10
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
Dezavantajele sunt legate de căderea întregului sistem în cazul oricărei defecţiuni a memoriei
şi de competiţia procesoarelor asupra acesteia. Ea nu numai că necesită un mecanism delicat de
interconectare a procesoarelor la memorie, dar scade dramatic scalabilitatea: orice nou procesor va
interfera cu cele deja existente, “încurcându”-le prin memoria pe care le-o va “fura”. Ca atare, aceste
arhitecturi nu pot practic folosi prea multe procesoare; peste un anumit prag, se înregistrează o
deteriorare continuă a performanţelor sistemului cu fiecare nou procesor adăugat. Singura soluţie viabilă
este cea cu un număr mic de procesoare, toate foarte puternice, ceea ce însă face ca această abordare
să fie adesea prea scumpă.
• fiecare procesor execută aceeaşi cerere, dar asupra unei alte porţiuni a datelor;
• interogarea este subdivizată în subinterogări şi fiecare procesor execută câte una dintre
acestea.
Prima abordare este, până în acest moment, cea mai răspândită în majoritatea sistemelor
paralele comerciale. În esenţă, ea implică o partiţionare prealabilă adecvată a datelor (iar pentru join - şi
replicarea celor mai mici tabele dacă discurile nu sunt partajate), procesarea paralelă a interogării şi o
reuniune finală a rezultatelor parţiale obţinute de fiecare procesor în parte.
Al doilea tip de abordare este abia la început, deoarece necesită un SGBD mult mai puternic,
capabil de descompunerea optimizată a interogărilor pentru platforme multiprocesor. În plus, lucrurile se
complică foarte mult în cazul arhitecturilor fără partajare, căci este nevoie ori de o optimizare globală, ori
de distribuirea optimizării între procesoare, provocare ce încă constituie o problemă deschisă în
domeniu.
11
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
SGBD orientate obiect (pure) diferă esenţial de cele relaţionale în foarte multe privinţe. Prima
dintre ele este desigur segmentul de piaţă vizat: în timp ce SGBD relaţionale au fost concepute, în
esenţă, pentru a susţine aplicaţii economico-financiare, SGBD obiectuale sunt mai degrabă proiectate
pentru aplicaţii CAD/CAM, CAP, CASE (i.e. aplicaţii asistate de calculator în domeniile proiectării,
publicisticii şi ingineriei software). De aici rezultă imediat câteva diferenţe cheie între condiţiile pe care
trebuie să le satisfacă cele două tipuri de abordări. Astfel, SGBD relaţionale trebuie să facă faţă
următoarelor provocări:
• tipurile de date sunt foarte simple, puţine şi mereu aceleaşi (şiruri de caractere, numere, date
calendaristice, constante Boolene); tabela este singura structură de date necesară;
• tranzacţiile sunt în majoritate scurte (în medie, sub un minut!) iar cele mai lungi sunt doar de
ordinul câtorva ore; însă timpul de răspuns este cel mai adesea critic;
• interogările sunt extrem de frecvente şi imprevizibile (atât ca expresie, cât şi ca moment al
lansării cererii);
• concurenţa este foarte mare (ajungându-se până la mii de utilizatori simultani cerând acces la
o aceeaşi dată);
• sunt necesare foarte multe tipuri de aplicaţii şi unelte de lucru pentru categorii foarte diferite de
utilizatori, în majoritate nespecialişti în programare (operatori, personal cu funcţii de conducere
la nivel operativ, mediu, directori, asociaţi etc.) dar şi administratori de bd şi programatori
specialişti (pentru care este importantă şi cuplarea la cât mai multe limbaje de programare);
• robusteţea facilităţilor sistem pentru securitatea accesului la date, recuperarea din eroare,
disponibilitatea bd şi optimizarea performanţelor este crucială;
• trebuie avute în vedere (şi interconectate) toate platformele de calcul cu putinţă, de la
calculatoare portabile până la mainframes.
Prin contrast, SGBD obiectuale trebuie să răspundă la alt tip de provocări, şi anume:
• sunt necesare tipuri şi structuri de date foarte complexe, imprevizibile (utilizatorii trebuie să-şi
poată mereu defini altele noi);
• tranzacţiile durează cel puţin câteva ore, media însă fiind de săptămâni! Ele trebuie întrerupte
şi reluate cel puţin zilnic; natura lucrului este iterativă, implicând adesea renunţarea la o parte
din lucru şi reluarea acestuia într-o altă variantă (fie că este vorba de proiectul pentru o clădire,
un cip, o instalaţie industrială, o revistă sau un SGBD!); este necesară memorarea şi
12
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
prelucrarea mai multor versiuni ale obiectelor; deşi foarte important, timpul de răspuns nu este
critic;
• interogările sunt mai rare şi foarte previzibile;
• concurenţa este mult mai mică (câţiva proiectanţi, maxim zeci);
• sunt necesare foarte multe unelte de lucru performante dar strict pentru specialişti în timp ce
eventualele unelte pentru alte categorii de utilizatori nu prea au mare importanţă; în schimb,
este esenţială cuplarea cu un limbaj de programare orientat obiect;
• facilităţile de securitate, recuperare din eroare, disponibilitate etc. nu sunt atât de importante;
• în general, platformele de lucru folosite sunt doar staţii de lucru (sau PC foarte performante)
interconectate într-un LAN sau cuplate la un SGBD server într-o arhitectură client / server.
Majoritatea SGBDO abordează această problemă cu ajutorul câte unei tabele a obiectelor
rezidente (în memorie) per client (TOR); fiecare rând al unei asemenea tabele, ce corespunde câte unui
obiect, are două coloane: identificatorul obiectului şi adresa din memorie la care rezidă descriptorul său
(acesta, la rândul lui, memorează desigur şi adresa la care rezidă obiectul propriu-zis). Înlănţuirea
obiectelor este implementată cu ajutorul pointerilor astfel: descrierea fiecărui obiect conţine un pointer
către descriptorul următorului obiect din lanţ; figura 9.1 ilustrează un TOR.
Această abordare nu este doar dictată de “swapping” (vezi mai jos), ci şi de considerente de
performanţă: în asemenea SGBDO, rezultatul oricărei interogări, de exemplu, este o mulţime de
descriptori (şi nu mulţimea obiectelor propriu-zise) nu doar pentru că memoria ocupată de obiecte este,
de obicei, mult mai mare decât cea necesară descriptorilor, dar şi pentru că, cel mai adesea, aplicaţiile
nu au efectiv nevoie de toate obiectele sau, măcar, nu de toate odată.
Atunci când SGBDO primeşte o cerere de acces la un obiect persistent al bd, el consultă TOR
(menţinută în memoria RAM) pentru a determina dacă obiectul este deja rezident în memorie sau nu.
Pentru mărirea vitezei de căutare în tabelă, aceasta este, de obicei, de tip “hashed” (“talmeş-balmeş”,
vezi capitolul 14) pe identificatorul obiectelor.
Dacă obiectul căutat nu există în tabelă (este deci prima cerere de acces la el), SGBDO îl cere
server-ului, îl converteşte din formatul disc în cel memorie (de obicei aceste formate diferă), îi găseşte
loc în RAM unde îl şi încarcă, îi construieşte un descriptor şi adaugă o linie corespunzătoare în TOR.
Drept urmare, un asemenea server se zice şi server obiect (căci unitatea de transfer cu clienţii este un
obiect).
Dacă, la un moment dat, gestionarul memoriei virtuale la dispoziţia SGBDO are nevoie de mai
multă memorie RAM decât a mai rămas disponibilă, el alege (conform unei strategii de tip cel mai rar
accesat, cel care nu a mai fost accesat de cel mai mult timp sau “în cerc” (“round-robin”) etc.) unul sau
mai multe obiecte rezidente pe care le mută într-un fişier temporar disc (“swapping”) eliberând astfel
memoria necesară. Descriptorii obiectelor astfel evacuate temporar din RAM rămân în memorie, dar
pointerul lor către obiectul propriu-zis corespunzător este anulat (devine nil). Ulterior, la o nouă cerere de
acces la un asemenea obiect, SGBDO îl va reîncărca în RAM din fişierul disc temporar, fără nici un
acces la server.
13
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
Un alt tip de implementare, mai nou, este cel folosit de serverele pagină. La acestea, formatul
de memorare al obiectelor este acelaşi pe disc şi în memoria RAM; transferul între server şi clienţi se
face nu la nivel de obiect ci de pagină (care, de obicei, conţine mult mai multe obiecte); nu mai există
TOR, ci doar o zonă a memoriei virtuale a fiecărui client în care sunt memorate pagini de obiecte; în
cazul în care se încearcă accesul la un obiect inexistent în această memorie, SGBDO procesează o
“capcană de pagină” ce are ca efect aducerea de pe server a paginii ce conţine obiectul respectiv; nu se
mai folosesc descriptori de obiecte, toţi pointerii indicând obiectele direct; ca atare, atunci când obiectele
sunt mutate în altă zonă a memoriei virtuale (de exemplu, ca efect al swapping-ului), pointerii spre ele
trebuie actualizaţi corespunzător. Desigur că, pentru anumite bd (în care o pagină conţine mai multe
obiecte) această abordare este mai performantă, atât datorită minimizării transferurilor client / server, cât
şi prin eliminarea indirectării referinţelor la obiecte prin descriptori.
Descriptor_O
ID_O Obiectul O
...
Orice element dintr-o colecţie (o mulţime ce admite duplicate!) este caracterizat simplu, doar
de un identificator id_ob şi un nume, plus un pointer urm_ob către următorul obiect al colecţiei. Funcţiile
membre ale acestei clase sunt şi ele reduse la minim: un constructor (pentru crearea de noi obiecte
membre ale colecţiei); un destructor (pentru eliminarea unui obiect din colecţie); şi un vizualizator (pe
ecran, al datelor despre un obiect). Declaraţia colecţie astfel definită este prezentată în figura 9.2. De
remarcat în corpul constructorului că, după asignarea primului şi ultimului parametru (componentelor
id_ob şi, respectiv, urm_ob), este întâi nevoie de a calcula lungimea celui de-al doilea parametru
(numele obiectului) şi de a aloca spaţiul corespunzător pentru el, instruind ObjectStore să memoreze
14
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
această informaţie în acelaşi segment al bd cu restul obiectului (lucru realizat de o formă supraîncărcată
a operatorului C++ “new”) înainte de a copia al doilea parametru în nume.
Figura 9.3 prezintă un program simplu ce creează obiecte persistente înlănţuite ale colecţiei
astfel definite şi le afişează. SGBDO ObjectStore deschide o bd anume (“/u/guest/testdb”, convenţia de
numire folosită conformându-se standardului Unix); după ce se obţine de la utilizator numărul dorit de
obiecte, SGBDO lansează o tranzacţie de actualizare date (“update”) şi se verifică dacă există deja
creată o rădăcină (punct de intrare) pentru lista înlănţuită a obiectelor colecţiei; în caz contrar, se
creează o asemenea rădăcină. După crearea şi listarea instanţelor create, sunt închise tranzacţia de
actualizare şi bd.
Integrarea în Internet
Cea mai fascinantă pagină din câte se scriu probabil în această perioadă în domeniul ştiinţei
calculatoarelor este probabil cea referitoare la spaţiul cibernetic asociat Internet-ului. Chiar dacă acest
subiect depăşeşte cu mult cadrul prezentei lucrări, am dori să menţionăm totuşi cele trei provocări
majore pe care considerăm că Internet le adresează SGBD:
• SGBD multimedia, pentru gestiunea nu doar a datelor numerice, text şi Boolene, ci şi a celor
audio-video;
• SGBD gestionând meta-date, despre ierarhiile laticeale de date disponibile în Internet
(structurare, căi de acces, eventual rezumate);
• mecanisme de fluidizare a traficului în reţea şi de garantare a accesului şi optimizare a costului
acestuia, în orice moment, la orice resursă de date, de la orice post de lucru conectat.
Desigur că fiecare dintre acestea în parte au fost deja abordate de industria SGBD, dar nu
încă sistematic şi masiv în contextul Internet, care, prin complexitatea, vastitatea, lipsa de omogenitate şi
viteza explozivă de dezvoltare (Japonia a început comercializarea pe piaţa sa a televizoarelor Sanyo,
Mitsubishi şi Sharp direct conectabile la Internet!) modifică de cele mai multe ori în chip radical datele
problemelor de proiectare şi implementare aferente.
Astfel, de exemplu, în SUA sunt deja operaţionale de câţiva ani SGBD multimedia de tip “filme
la cerere” (“video-on-demand”) prin care companii de televiziune prin cablu oferă abonaţilor nu doar filme
preprogramate de compania respectivă, ci le permit acestora să-şi aleagă dintr-o bd de filme ce
programe doresc fiecare să vizioneze şi la ce oră anume! Despre meta-date vom vorbi mai în amănunt,
dar doar în contextul SGBD, în capitolul 16. La fel, despre fluidizarea traficului în reţele de calculatoare,
despre garantarea accesului la date şi optimizarea acestuia în condiţii de concurenţă vom discuta în
următoarele capitole, dar, iarăşi, din păcate, nu şi în contextul Internet-ului.
Încă o dovadă (dacă mai era nevoie!) că viteza de evoluţie în domeniul acesta este
extraordinară o constituie lansarea recentă pe piaţă (după redactarea lucrării, dar înainte de susţinerea
ei!) de către Microsoft a pachetului Office97, proiectat şi realizat folosind tehnologiile Internet (format
HTML, hiperlegături, navigare Web etc.) pentru cuplarea oricărui PC la Internet, din orice componentă a
sa, inclusiv din SGBD Access’97.
Principala caracteristică remarcabilă a acestei noi versiuni este aceea că utilizatorii PC pot
crea pagini Web conţinând imagini active ale datelor, astfel încât navigatoarele Web pot actualiza, şterge
sau adăuga informaţii. În plus, datele pot fi sincronizate prin replicare între calculatoarele conectate,
astfel încât ultima lor versiune să fie tuturor accesibilă rapid. Într-un viitor extrem de apropiat, întreaga
planetă va fi acoperită de o unică bd distribuită, plină cu PC-uri nu doar client ci şi server de date!
Mai mult, tehnologia Internet este, prin Office97, disponibilă şi în LAN (referite acum ca
Intranet) faţă de care nu mai există, practic, nici o diferenţă!
15
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
class colecţie
public:
// date membru publice
int id_ob; // identificator obiect
char *nume; // pointer către numele obiect
colecţie *urm_ob; // pointer către următorul obiect al colecţiei
// funcţii (metode) membru publice
colecţie(const int, char*, colecţie*); // constructorul de obiecte
~colecţie(); // destructorul de obiecte
void afişează(); // vizualizatorul obiectelor instanţiate
;
// corpul funcţiilor membru publice
// creare specificaţii de tip pentru ObjectStore (obligatorii pentru toate
// tipurile/clasele pentru care se cere instanţierea de obiecte persistente)
extern os_typespec char_type;
// destructorul dual
colecţie::~colecţie()
// şterge spaţiul alocat obiectului nume
delete nume;
16
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
main()
// iniţializare variabile
colecţie *head = 0; // capul listei înlănţuite de obiecte
int număr = 0; // numărul de ID obiect
char nume_ob[32]; // vector pentru numele obiect
int total = 0; // numărul total de obiecte
os_database *db1 = 0; // pointer la o bd ObjectStore
os_database_root *root = 0; // pointer la o rădăcină ObjectStore
os_typespec col_type(“colecţie”)
objectstore::initialize();
db1 = os_database::open(“/u/guest/testdb”, 0, 0666);
OS_BEGIN_TXN(t1, 0, os_transaction::update)
root = db1→find_root(“col_root”);
if (!root) root = db1→create_root(“col_root”);
head = (colecţie*)root→get_value();
// crează obiectele
for (int i = 0; i < total; i++)
cout << “Specificaţi ID următorului obiect dorit: “<< endl;
cin >> număr;
cout << “Specificaţi numele următorului obiect dorit: “<< endl;
cin >> nume_ob;
head = new(db1, 1, &col_type)
colecţie(număr, nume_ob, head);
root→set_value(head);
// afişează toate obiectele colecţiei
cout << “Lista tuturor obiectelor colecţiei create: “<< endl;
for (colecţie* e = head; e; e = e→urm_ob)
e→afişează();
OS_END_TXN(t1)
db1→close();
Figura 9.3 Program ObjectStore pentru crearea şi afişarea de obiecte persistente
17
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
În această secţiune prezentăm doar câte o vedere de ansamblu asupra lor; ultima secţiune (de
comentarii şi referinţe bibliografice) a fiecărui capitol din această ultimă parte este în principal dedicată
modului în care sunt implementate considerentele teoretice dezvoltate anterior în aceste SGBD celebre.
Pe lângă acestea, sporadic, apar şi referiri la Microsoft SQL Server [262], Microsoft Access’95
[154,259], Microsoft Visual FoxPro [261] şi Borland Paradox [74,255].
E.F. Codd, părintele modelului relaţional al datelor (perioadă în care era cercetător al IBM!),
este şi părintele DB2, chiar dacă indirect, prin prototipul System R. DB2 este un SGBD complet,
încorporând toate funcţiunile cunoscute în domeniu, înclusiv distribuirea datelor şi procesarea paralelă.
Informaţiile furnizate în această a treia parte se referă la versiunea 3, curentă în acest moment, dar sunt
incluse şi principalele îmbunătăţiri anunţate pentru versiunea 4 ce abia a fost lansată comercial.
Trebuie notat şi faptul, deloc neglijabil, că DB2 este oferit de IBM împreună cu familii întregi de
utilitare şi de alte produse IBM cu care DB2 cooperează: compilatoare şi interpretoare pentru aproape o
duzină de limbaje de programare (vezi capitolul 17), aplicaţii de tip suport decizii (gestionarul
interogărilor, vizualizatorul datelor etc.), instrumente de asistenţă a dezvoltării aplicaţiilor (VisualGen,
VisualAge), unelte pentru administratorii de sistem (DataHub, DB2PM, Estimator, DFSMS, RACF etc.)
etc. În plus, o întreagă industrie complementară gravitează în jurul DB2 (al IBM în general!) oferind
diverse alte produse ale altor firme, atât completând (sau chiar concurând) cele ale IBM, cât şi oferind
alte tipuri de aplicaţii, unelte şi conectivitate.
Analiza noastră are în vedere versiunea curentă, 7.1, a serverului Oracle; acesta poate fi
achiziţionat singur sau împreună cu opţiunile pentru bd distribuite (Distributed Option) şi/sau pentru
medii de procesare paralelă (Parallel Server Option şi Parallel Query Option). Şi SGBD Oracle este
furnizat în centrul a numeroase familii de produse complementare ale firmei Oracle şi ale altor furnizori
18
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
de software. Mai interesant în această privinţă este însă “Cooperative Development Environment” (CDE)
ce reprezintă încercarea Oracle de a furniza o mulţime de oferte integrate care să acopere întreg ciclul
de viaţă al dezvoltării aplicaţiilor.
SQL Server al Sybase a fost folosit, prin contract, până în 1994 şi de Microsoft (întâi doar sub
OS/2, apoi şi pentru Windows NT). De atunci, între cele două companii a intervenit competiţia, Microsoft
achiziţionând patentul versiunii 4.2 şi începând modificările şi dezvoltarea unui Microsoft SQL Server
propriu.
NonStop SQL este unul dintre cele mai moderne şi performante SGBD relaţionale de pe
piaţă, proiectat şi construit pentru medii distribuite formate din noduri de calcul cu procesare paralelă. El
include o interfaţă conversaţională pentru SQL (SQLCI) şi suport pentru C, Pascal şi COBOL. Firma mai
oferă utilitare pentru administrarea sistemului, precum şi facilităţi reţea, inclusiv “gateways” către Oracle,
Sybase şi Windows. Mulţi alţi furnizori de software oferă produse suplimentare pentru NonStop SQL.
Redenumită ulterior Ingres, Relational Technology este achiziţionată în 1990 de grupul ASK
(specializat în software pentru industria constructoare de maşini). Din 1994, “ASK Ingres” a fost
cumpărată de puternicul concern Computer Associates.
Acum numit CA-OpenIngres, acest SGBD rulează pe mai mult de 35 de tipuri de platforme
hardware, în marea majoritate însă sub Unix şi VMS. El include facilităţi client / server şi de bd distribuite
19
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
(prin interfaţa Ingres / Net), plus The Knowledge Manager, care asigură mecanisme de controlul
integrităţii datelor şi utilizării resurselor. Opţiunea Object Manager, orientată obiect, oferă posibilitatea
definirii de tipuri de date şi metode utilizator. Informaţiile din această ultimă parte se referă la versiunile
curente ale tuturor acestor componente şi în special la versiunea R6.4 a motorului Ingres / Star al
SGBD.
Dintre articolele specializate privitoare la arhitecturi client / server, recomandăm pe cele din
1994 ale lui David Linthicum [227,228]. Din multitudinea de texte privitoare la sisteme deschise şi bd
distribuite, semnalăm excelentele contribuţii ale lui Bernstein [65] şi ale IBM Corp. [179,180]. Pentru
mediile de procesare paralelă, Hsiao [174] şi, din nou, o echipa IBM [265] reprezintă certe autorităţi în
domeniu.
SGBD orientate obiect sunt analizate în profunzime de câteva texte de referinţă, dintre care se
disting contribuţiile lui Kemper şi Moerkotte [196], Stonebraker [325] şi Jacobson and al. [186].
Cadrul restrâns al acestei lucrări nu permite tratarea în mai mare detaliu a abordărilor orientate
obiect existente în acest domeniu în care, deocamdată, lipseşte vreun model unitar sau vreo
standardizare. Totuşi, în 1993, un număr de companii importante în domeniu (incluzând Object Design,
Ontos, OS2 Technology, Objectivity şi Versant) au format “Object Database Management Group” cu
scopul de a schiţa un standard pentru un model obiectual al datelor şi un limbaj de programare pentru
SGBD orientate obiect [29]. Acestea includ limbaje de definire şi manipulare a obiectelor, un limbaj non-
procedural de interogare obiectual (parţial bazat pe SQL) şi punţi de legătură către Smaltalk şi C++.
SGBD ObjectStore cu care am exemplificat abordarea orientată obiect în subsecţiunea 9.6.2 este
descris în [220].
Despre Internet “curge” probabil deja în lume un fluviu de cărţi şi articole! Dintre ele,
recomandăm măcar [188].
Pentru informaţiile referitoare la cele 5 SGBD celebre analizate în partea a treia a lucrării, am
apelat la următoarele surse bibliografice:
• pentru DB2, [104, 116, 122, 167, 180]
• pentru Oracle, [273]
• pentru SQL Server al Sybase, [327]
• pentru NonStop SQL al Tandem, [328]
• pentru CA-OpenIngres, [323]
20
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
2. CONTROLUL CONCURENŢEI
Lacăte
Gestiunea accesului concurent la bd de către mai mulţi utilizatori simultan trebuie să garanteze
consistenţa şi integritatea datelor. Cel mai simplu mod de a le asigura este, evident, serializarea
tranzacţiilor, adică punerea într-o coadă de aşteptare a tuturor tranzacţiilor şi execuţia lor pe rând, una
câte una (într-o ordine oarecare, bazată, de exemplu, pe priorităţi şi ordinea cronologică de lansare), pe
măsură ce execuţia tranzacţiiilor precedente se încheie. Această strategie de implementare a controlului
concurenţei nu poate fi însă aplicată de nici un SGBD din cauza performanţelor complet neacceptabile
ce ar fi astfel oferite.
Exemplul 10.1
De exemplu, să considerăm o firmă cu doi asociaţi şi un singur cont în bancă. Într-o zi,
în care, de exemplu, soldul contului este de 1.000.000 lei, simultan, ambii asociaţi se duc
fiecare la câte o altă sucursală a băncii care le gestionează contul, primul dorind să facă
o plată prin bancă de 500.000 lei, iar al doilea dorind să retragă din cont 300.000 lei. Deşi
este evident că, dacă cele două tranzacţii sunt corect serializate, la sfârşitul lor soldul
contului ar trebui să fie de 200.000 lei, în absenţa unui mecanism de control al
concurenţei de tipul lacătelor soldul final ar putea fi incorect, de exemplu, în următoarea
situaţie:
1. Funcţionarul primei sucursale citeşte din bd soldul de 1.000.000 al contului.
2. Funcţionarul celei de-a doua sucursale citeşte din bd soldul de 1.000.000 al contului.
3. Funcţionarul primei sucursale operează plata de 500.000 şi scrie soldul final de 500.000
(1.000.000 - 500.000).
4. Funcţionarul celei de-a doua sucursale operează retragerea de 300.000 şi scrie soldul final
de 700.000 (1.000.000 - 300.000).
În acest mod, rezultatul primei tranzacţii s-a pierdut, căci cea de-a doua a rescris-o!
În majoritatea SGBD moderne, lacătele sunt puse şi scoase automat de sistem, fiind deci
transparente utilizatorilor. Deoarece acest lucru încă ar putea conduce, în anumite situaţii, la ineficienţa
sistemului, se permite şi programatorilor să controleze lacătele prin instrucţiuni dedicate de punere şi
scoatere a acestora. Pentru atingerea unui compromis cât mai acceptabil între controlul automat şi cel
manual, sunt practic utilizate mai multe tipuri de lacăte iar datele sunt blocate cu lacăte pe mai multe
niveluri, aşa cum se va vedea în subsecţiunile următoare.
21
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
orice alte lacăte, în sensul că o tranzacţie nu poate pune un asemenea lacăt pe nişte date, decât după
scoaterea tuturor altor lacăte de pe acele date. Lacătele partajabile sunt compatibile între ele, adică orice
tranzacţie poate pune un asemenea lacăt pe nişte date care mai sunt deja blocate de alte tranzacţii, tot
cu lacăte partajabile. Figura 9.1 prezintă un exemplu de control al concurenţei mai multor tranzacţii
folosind lacăte partajabile şi exclusive.
Diverse SGBD comerciale oferă şi alte tipuri de lacăte în afara acestora două fundamentale
deja discutate; câteva dintre ele vor fi trecute în revistă în ultima secţiune, de comentarii, a acestui
capitol.
Granularitatea
Pe lângă diversele tipuri de lacăte oferite, SGBD asigură şi diferite niveluri de control al blocării
datelor. Acestea determină granularitatea lacătelor suportate de sistem, care poate varia de la o
întreagă bd, la un fişier sau un articol dintr-un fişier. Diverse tipuri de lacăte pot fi folosite pe diverse
niveluri de granularitate.
22
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
Raţiunea de a introduce mai multe niveluri de granularitate este evidentă: unele tranzacţii
(precum cele din exemplul 9.1 de mai sus) pot avea nevoie de acces (ACID!) la mai multe date odată, în
timp ce altele (precum cele din exemplul 10.1 de mai sus) au nevoie de acces (ACID!) la o singură dată.
Majoritatea SGBD-urilor oferă cel puţin trei niveluri de granularitate: articol fişier (rând din
tabelă); pagină; fişier (tabelă). Paginile de date sunt unităţi de alocare a memoriei pe disc, a căror
dimensiune, multiplu de 2Koct., variază în funcţie de sistemul de operare şi de SGBD (tipic, între 2K şi
64K). În general, o pagină conţine un număr întreg de articole, iar un fişier se întinde pe mai multe
pagini. În unele SGBD, o pagină poate conţine articole din mai multe fişiere (cu date structural legate
între ele). Deşi paginile de date nu sunt conceptualizate de modelele de date suport ale SGBD, totuşi
acest nivel de granularitate are sens, aşa cum rezultă din următorul exemplu:
Exemplul 10.2
Unele SGBD evoluate oferă în plus un mecanism automat de “escalare a lacătelor” (sau
“blocare progresivă”) pentru mărirea performanţelor sistemului: atunci când un lacăt cu granularitate
prea fină este repetat pus (încărcând excesiv sistemul) SGBD poate decide (dincolo de un prag setabil)
că ar fi mai economic să mărească granularitatea, înlocuind lacătul cu unul mai larg (de exemplu, de la
articol la pagină sau chiar la fişier). Această mărire progresivă a granularităţii este făcută automat, fiind
transparentă tranzacţiei implicate.
Stabilitatea cursorului
Stabilitatea cursorului impune SGBD să blocheze datele doar atâta timp cât ele sunt cele
curente. Atunci când cursorul (care indică articolul curent al fişierului din care se citeşte) este mutat pe
alte date decât cele curent blocate, sistemul scoate automat lacătul (partajabil) asociat datelor ce nu mai
sunt indicate de cursor. Evident că această izolare a lacătelor de citire este duală primeia, mărind
23
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
concurenţa; există însă tranzacţii pentru care ea este inaplicabilă deoarece, desigur, o recitire ulterioară
a aceloraşi date poate furniza valori diferite de citirea anterioară (căci, între timp, alte tranzacţii au putut
modifica datele respective).
Datorită experienţei oferite de bd distribuite însă, s-a dovedit că această variantă iniţială încă
nu garantează serializabilitatea! Pentru a o obţine, mai este necesară adăugarea unei noi restricţii:
scoaterea lacătelor nu se poate face decât la terminarea tranzacţiei (aşa încât faza de restrângere ar
putea fi mai plastic denumită fază de dezumflare). Necesitatea acestei restricţii suplimentare poate fi
ilustrată cu ajutorul exemplului 9.3 (de unde se poate observa că problema este mai generală, nu doar
pentru bd distribuite, chiar dacă riscurile apariţiei unei situaţii similare cresc exponenţial de la platforme
uni-procesor neinterconectate, la mediile de procesare paralelă şi apoi la bd distribuite):
Exemplul 10.3
24
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
Blocaje fatale
Ca în orice alt tip de control al concurenţei utilizând mecanisme de blocare şi SGBD trebuie să
evite o potenţială problemă majoră: blocajele fatale (“deadlocks”). Un asemenea blocaj poate apărea
ori de câte ori fiecare dintre tranzacţiile concurente la un moment dat sunt în aşteptarea (circulară) a
alteia dintre ele. Cel mai simplu exemplu este cel cu doar două tranzacţii concurente, dintre care prima a
blocat data d1 şi aşteaptă să poată bloca şi data d2, iar cea de-a doua a blocat data d2 şi aşteaptă să
poată bloca şi d1. Evident că, în acest caz, nici una dintre ele nu mai poate continua vreodată, iar
sistemul este blocat în mod fatal (numai o repornire a sa putând debloca situaţia, desigur cu pierderile de
informaţii şi integritate a datelor aferente).
SGBD mai performante, din noile generaţii, oferă mecanisme de prevenire a blocajelor fatale:
toate lacătele necesare unei tranzacţii la un moment dat pot fi cerute şi se garantează sau se resping
simultan, în mod atomic (în bloc). Desigur că preţul evitării apariţiei blocajelor fatale în acest mod este
însă reducerea concurenţei. În cazul exemplului de mai sus, presupunând că prima tranzacţie a cerut şi
obţinut blocarea simultană a datelor d1 şi d2, cea de-a doua tranzacţie nu le va mai putea bloca până
când prima nu le eliberează.
Prevenirea blocajelor fatale este făcută de SGBD prin menţinerea unor “grafuri de aşteptare”
(“wait-for graph”) orientate: în ele sunt memorate atât tranzacţiile care au obţinut lacăte, cât şi cele care
sunt în aşteptare deoarece au cerut lacăte ce nu pot fi momentan garantate. Nodurile unui astfel de graf
memorează identificatorii tranzacţiei şi ai datelor blocate sau a căror blocare e cerută, precum şi tipul
lacătului, în timp ce orice arc orientat indică dinspre o dată blocată de o tranzacţie către o altă tranzacţie
ce aşteaptă blocarea aceleiaşi date. Evident că orice buclă închisă într-un asemenea graf indică un
blocaj fatal. Sarcina SGBD este deci de a preveni mereu închiderea vreunei bucle.
Exemplul 10.4
distribuită. Dezavantajele sunt pierderea autonomiei locale şi, mai ales, aglomerarea traficului în reţea,
plus riscurile inerente dependenţei de un singur server.
Cea mai interesantă propunere alternativă pare cea avansată, încă din 1982, de cercetătorul
Ron Obermark de la IBM [271]: se extinde graful de aşteptări cu un nou tip de noduri care, împreună cu
arcele aferente, să memoreze informaţii de tipul “tranzacţia locală T este în aşteptarea terminării
tranzacţiei cohortă T’ pe care a iniţiat-o”, respectiv “tranzacţia cohortă U’ este aşteptată să se termine de
tranzacţia U ce a iniţiat-o”. Apariţia unui asemenea tip de nod într-un graf de aşteptare este considerată
de SGBD drept un potenţial de blocaj fatal global şi declanşează imediat trimiterea subgrafului de
aşteptare relevant celuilalt SGBD implicat; acesta, reunindu-l cu graful propriu de aşteptare, poate astfel
preveni apariţia vreunui blocaj fatal global.
Aceste niveluri nu sunt însă mutual exclusive: în practică, DB2 foloseşte diverse combinaţii de
“lacăte de intenţie” (“intent locks”), de nivel spaţiu tabelă şi tabelă, cu lacăte de pagină şi rând pentru a
obţine un echilibru cât mai bun între necesităţile conflictuale de asigurare a unei cât mai mari concurenţe
şi de evitare a blocajelor fatale. Există trei asemenea tipuri suplimentare de lacăte: “intenţia partajării”,
“intenţia exclusivităţii” şi “partajabil cu intenţia exclusivităţii”. Înainte de a obţine un lacăt pe o pagină,
DB2 încearcă, în general, obţinerea unui lacăt de intenţie corespunzător. Astfel,
• intenţia partajării este cerută pentru operaţiile exclusiv de citire; el permite tranzacţiei
tentative ulterioare de obţinere de lacăte non-exclusive asupra paginilor tabelei sau spaţiului
respectiv; celelalte tranzacţii pot şi ele citi concurent aceste pagini;
• intenţia exclusivităţii este cerută doar pentru operaţiile de scriere asupra mai multor pagini
ale unei tabele sau spaţiu de tabele; el permite tranzacţiei cererea ulterioară a oricărui tip de
lacăt asupra paginilor; celelalte tranzacţii concurente pot, la rândul lor, obţine orice fel de lacăte
asupra paginilor vizate;
• partajabil cu intenţia exclusivităţii este similar cu intenţia excusivităţii; diferenţa rezidă doar
în faptul că celelalte tranzacţii concurente nu mai pot obţine lacăte exclusive pentru scrierea în
vreo pagină a tabelei sau spaţiului respectiv; numele lacătului sugerează chiar faptul că acesta
este o conjuncţie a două lacăte: partajabil (care împiedică deci obţinerea unui lacăt exclusiv de
vreo altă tranzacţie) şi intenţia exclusivităţii.
26
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
“factorizează” într-un sens tipurile de blocaj concomitent posibile asupra paginilor unei tabele/spaţiu şi
scutesc DB2 să analizeze, de fiecare dată, lacătele tuturor paginilor implicate.
Programatorii pot decide modul iniţial de blocare folosit de sistem cu instrucţiunea LOCK
TABLE; astfel, ei pot cere direct un lacăt partajabil sau exclusiv asupra oricărei tabele (pentru spaţii de
tabele segmentate se pot obţine astfel doar lacăte cu intenţie partajabilă, respectiv exclusivă asupra
spaţiului, pe lângă lacătul cerut asupra tabelei).
Pe lângă stabilitatea cursorului (zisă aici “acces stabil”) şi citirea repetabilă (zisă “acces
repetabil”) mai este oferit un nivel suplimentar de izolare: “acces inspecţie” (“browse access”).
Tranzacţiile operând în acest mod nu au nevoie de nici un lacăt; ele pot doar citi orice date, inclusiv cele
tocmai în curs de modificare de către o altă tranzacţie (ca atare, nu acesta este modul implicit de
acces!); evident însă că acest mod de acces contribuie decisiv la mărirea concurenţei, chiar dacă trebuie
folosit doar de tranzacţiile ce nu depind critic de valorile exacte ale datelor.
Optimizatorul NonStop SQL (vezi capitolul 15) alege şi gestionează automat, folosind la
nevoie escalarea, lacătele necesare. Totuşi, sistemul permite utilizatorilor (cu ajutorul instrucţiunii
CONTROL TABLE) să controleze durata lacătelor (zise, în acest caz, “lacăte silite”, în engleză
“bounce locks”), tipul lor şi nivelurile de izolare. Dacă sistemul are nevoie de o resursă blocată cu un
27
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
lacăt silit, el nu aşteaptă însă pur şi simplu eliberarea resursei ci semnalează aplicaţiei o eroare
(excepţie); aceasta va lua măsurile pe care le crede de cuviinţă în contextul respectiv. Operând mai
degrabă la nivelul instrucţiunilor SQL (decât la nivelul liniilor, tabelelor sau tranzacţiilor), lacătele silite
permit programatorilor scheme de blocare mai sofisticate decât cele automat implementate de sistem.
Blocajele fatale sunt rezolvate doar prin “time out” (nu cu grafuri de aşteptare)!
Oracle este unic în modul de rezolvare a controlului concurenţei asupra liniilor din tabele: el nu
împiedică citirea datelor în timpul actualizării lor, fără însă a oferi la citire date “murdare”; acest lucru este
realizat cu ajutorul unor “fotografii” (”snapshot”) ale datelor făcute ori de câte ori este nevoie iar datele
sunt consistente. De exemplu, înainte de a garanta unei tranzacţii blocarea exclusivă a unei linii, aceasta
este fotografiată, urmând ca, apoi, în timp ce linia este modificată, tranzacţiile care doresc să o citească
să îi aibă la dispoziţie fotografia.
Ca atare, la nivel de linie, nu există, de fapt, lacăte partajabile, ci doar exclusive. La nivelul
tabelelor există însă următoarele cinci tipuri de lacăte:
• Lacătele partajabile pe (grupuri de) linii implică faptul că tranzacţia a blocat un număr de linii al
unei tabele pentru a le modifica; ele sunt garantate instrucţiunilor de tip SELECT ... FROM ...
FOR UPDATE OF; alte tranzacţii pot actualiza sau obţine lacăte asupra celorlalte linii
neblocate ale tabelei, dar nu pot bloca tabela în mod exclusiv.
• Lacătele exclusive pe (grupuri de) linii sunt similare, diferenţele constând în faptul că ele sunt
garantate instrucţiunilor INSERT, UPDATE şi DELETE şi că celelalte tranzacţii nu pot bloca
tabela nici măcar în mod partajabil.
• Lacătele partajabile sunt garantate doar de instrucţiunea LOCK TABLE ... IN SHARE MODE;
ele interzic altor tranzacţii să actualizeze tabela; dacă însă nu există tranzacţii concurente care
să deţină acelaşi tip de lacăt asupra tabelei, acest lacăt permite obţinerea de lacăte de linie
(pentru actualizarea acestora).
• Lacătele exclusive cu linii partajabile sunt garantate doar de instrucţiunea LOCK TABLE ...
IN SHARE ROW EXCLUSIVE MODE; o singură tranzacţie poate deţine la un moment dat un
asemenea lacăt pe o tabelă; ea poate actualiza orice linie a tabelei în timp ce alte tranzacţii le
pot citi (direct, sau fotografiile corespunzătoare, după caz); nici o tranzacţie nu poate însă
obţine în acest timp vreun lacăt partajabil, exclusiv sau exclusiv cu linii partajabile asupra
tabelei.
• Lacătele exclusive sunt garantate doar instrucţiunilor LOCK TABLE ... IN EXCLUSIVE MODE;
tranzacţia poate scrie, alte tranzacţii pot citi fotografia curentă a tabelei, dar nici o altă
tranzacţie nu poate deţine vreun lacăt asupra tabelei.
28
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
execuţiei interogării. Aceasta înseamnă, în esenţă, două lucruri: oricât de mult ar dura execuţia
interogării, ea va accesa mereu aceleaşi valori ale datelor cu cele care erau memorate la momentul
începerii execuţiei ei; pe de altă parte însă, tranzacţiile concurente pot lucra în paralel, inclusiv pentru a
actualiza datele procesate de interogare.
Acest model se mai numeşte şi tehnica de interogare fără blocaje, deoarece nici cititorii nu
blochează scriitorii şi nici invers. Interogările văd mereu date consistente (absolut consistente, nu doar
relativ consistente, precum în cazul stabilităţii cursorului) chiar dacă acestea nu sunt cele mai recente.
Implementarea acestui model este relativ simplă: ori de câte ori o tranzacţie se termină, în
jurnalul de actualizări corespunzător este memorată şi valoarea curentă a unui număr de schimbări
sistem (SCN) care, apoi, este imediat incrementată; fiecare bloc de date memorat pe disc conţine şi
valoarea SCN la momentul ultimei scrieri a datelor blocului respectiv; la momentul începerii execuţiei
unei interogări, Oracle memorează valoarea curentă a SCN; atunci când interogarea accesează un bloc
de date, acesta este livrat direct dacă SCN-ul său este mai mic sau egal cu cel memorat la începutul
tranzacţiei; în caz contrar, Oracle reconstruieşte, cu ajutorul jurnalului de actualizări, o fotografie a
datelor conformă cu starea lor la momentul începerii tranzacţiei.
Modelul consistenţei multi-versiune poate fi însă schimbat de utilizatori explicit pentru a obliga
Oracle să impună consistenţa citirilor la nivelul tranzacţiilor în locul celei de nivel instrucţiune.
Aceasta garantează tuturor instrucţiunilor unei tranzacţii (în particular, tuturor interogărilor deci) accesul
la o versiune consistentă a datelor, ceea ce este comparabil cu citirile repetabile.
Pentru tranzacţiile care scriu, este necesară în acest caz obţinerea în prealabil de lacăte
exclusive de linii sau de tabelă (interogările componente ce doar citesc date având nevoie numai de
lacăte exclusive de linii). Acest lucru determină, desigur, o scădere a concurenţei. Dacă tranzacţiile doar
citesc (şi nu au deci nevoie de nici un fel de lacăt exclusiv), ele pot semnala acest lucru, pentru a permite
o concurenţă mărită, prin instrucţiunea SET TRANSACTION READ ONLY; ea are ca efect garantarea
consistenţei de către Oracle cu ajutorul SCN, similar ca mai sus.
Controlul utilizatorilor asupra concurenţei este extins şi în cazul instrucţiunilor SELECT ... FOR
UPDATE prin clauza NOWAIT; în prezenţa acesteia, dacă sistemul nu poate garanta imediat lacătul
partajabil pe grupul de linii corespunzător, el nu pune tranzacţia în aşteptarea momentului în care acesta
va putea fi garantat (ca în cazul implicit, când opţiunea NOWAIT lipseşte) ci semnalează tranzacţiei o
eroare, pe care aceasta o tratează cum crede de cuviinţă.
Pentru prevenirea blocajelor fatale, Oracle menţine grafuri de aşteptare; dacă este nevoit să
aleagă o victimă, atunci îi “desface” doar ultima dintre instrucţiuni, cea care a provocat blocajul,
pasându-i un mesaj în acest sens; tranzacţia în cauză poate decide să se “desfacă” integral, sau să
aştepte şi să reîncerce apoi instrucţiunea. În contextul bd distribuite, eventualele blocaje globale fatale
sunt rezolvate prin “time out”.
• Actualizare; folosit doar în primul pas al unei operaţii de actualizare (de pregătire a scrierii), în care
pagina este doar citită în memorie; în acest răstimp, alte tranzacţii pot citi şi ele pagina; când
tranzacţia a terminat actualizarea datelor în memorie, înainte de a le scrie pe disc trebuie să obţină
un lacăt exclusiv asupra paginii.
29
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
• Cerere; atunci când o tranzacţie are de scris o pagină şi nu are timp de aşteptat după tranzacţiile
care citesc, poate cere un asemenea lacăt; sistemul o va promova în capul listei de aşteptare şi nu
va mai garanta nici un alt lacăt partajabil asupra paginii până când tranzacţia nu termină de scris.
• Cerere, idem.
• Exclusiv, idem, cu observaţia că, în general, blocarea exclusivă se face doar la nivel de pagină;
numai instrucţiunile UPDATE şi DELETE ce nu referă coloane indexate necesită acest tip de lacăt.
• Intenţie de partajare; folosit pentru citiri; proprietarul poate ulterior cere blocarea cu lacăte partajabile
a oricăror pagini ale tabelei (ce îi vor fi garantate, evident, doar dacă ele nu sunt blocate exclusiv de
vreo altă tranzacţie); el este garantat interogărilor care referă atât coloane indexate, cât şi
neindexate.
• Intenţie de exclusivitate; folosit pentru scrieri; proprietarul poate încerca ulterior obţinerea de lacăte
de scriere pentru oricare pagină a tabelei (ce vor reuşi, desigur, doar dacă paginile respective nu sunt
blocate de alte tranzacţii), dar şi de lacăte partajabile sau de actualizare; el este garantat pentru
inserţii, dar şi pentru actualizări şi ştergeri dacă acestea referă coloane indexate.
SQL Server încurajează utilizarea de lacăte de pagină, pentru mărirea concurenţei; dacă
totuşi o singură instrucţiune blochează mai mult de 200 de pagini ale unei tabele, sistemul escalează
automat lacătul la cel de tabelă.
O funcţie permite utilizatorilor să menţină lacătele partajabile asupra unei tabele până la
terminarea tranzacţiei. Aceasta, coroborată cu instrucţiunea SET TRANSACTION ISOLATION LEVEL 3,
oferă suport pentru citiri repetabile.
SQL Server menţine grafuri de aşteptare pentru prevenirea blocajelor fatale; drept “victimă” va
fi aleasă întotdeauna (pentru a fi “desfăcută”) tranzacţia implicată ce a consumat cel mai puţin timp
procesor.
Astfel, datele pot fi citite şi fără a cere un lacăt partajat, cu SET LOCKMODE SESSION
WHERE READLOCK = NOLOCK; desigur că aceasta măreşte concurenţa, scade probabilitatea
blocajelor fatale, dar poate oferi date “murdare”, inconsistente. Similar, pot fi escalate explicit lacătele de
pagină la nivelul tabelei, sau poate fi modificat pragul de escalare automată de către sistem (implicit,
acesta este de 10 pagini blocate per tabelă).
30
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
Cu aceeaşi instrucţiune, utilizatorii pot obliga sistemul să nu aştepte la infinit garantarea unui
lacăt, ci doar în limita valorii indicată de opţiunea TIMEOUT; la scurgerea acestui interval de timp,
sistemul “desface” instrucţiunea curentă a tranzacţiei în aşteptare şi îi semnalează o eroare; tranzacţia o
va procesa cum crede de cuviinţă (reîncercând instrucţiunea “desfăcută” sau renunţând şi “desfăcându-
se” complet).
Ingres suportă opţional stabilitatea cursorului, deşi citirile repetabile sunt implicit asumate. De
asemenea, sunt prevenite blocajele fatale; victima aleasă este complet “desfăcută”, lucru memorat în
jurnalul de actualizări.
31
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
Strategiile de salvare a datelor sunt foarte diferite de la SGBD la SGBD; de exemplu, se pot
face salvări ale datelor dintr-o tabelă, dintr-un grup de tabele (logic interconectate sau doar create de un
acelaşi utilizator), dintr-o bd sau dintr-o colecţie de bd. Unele SGBD salvează doar datele propriu-zise, în
timp ce altele adaugă şi alte informaţii (de exemplu, restricţiile de securitate asociate). SGBD evoluate
măresc performanţa lucrului oferind salvări în timp real (“on-line”) pentru bd care trebuie să fie
disponibile clipă de clipă.
Folosind salvările (integrale şi/sau parţiale) SGBD pot reface starea bd corespunzătoare
ultimei salvări, asigurând astfel cea mai banală recuperare din erori cu putinţă. Aceasta însă nu poate fi
întotdeauna mulţumitoare, căci readucerea bd în starea din momentul erorii poate fi foarte costisitoare
dacă salvările nu sunt suficient de recente. Ca atare, pe lângă salvări, SGBD menţin în plus şi jurnale
de actualizări.
Jurnale de actualizări
Un jurnal de actualizări memorează modificările datelor dintr-o bd; el este de obicei memorat
tot pe disc dur, într-un fişier separat de cele ale bd (plasat adesea, pentru mărirea siguranţei, pe un alt
disc decât cel pe care rezidă bd). Unele SGBD oferă chiar precauţia menţinerii câte unui jurnal oglindă,
copie fidelă a fiecărui jurnal, memorată pe alt disc decât jurnalul original, pentru maximă securitate.
Deşi nu există nici în cazul jurnalelor de actualizări vreo soluţie standard, majoritatea SGBD
memorează în aceste jurnale momentul începerii şi terminării execuţiei fiecărei tranzacţii, ca şi vechile şi
noile valori ale datelor pentru fiecare actualizare de date în parte (evident împreună cu numele
tranzacţiei corespunzătoare).
Cum toate scrierile pe disc se fac grupat, pe zone tampon relativ mari (pentru a mări viteza
prin micşorarea numărului de accese la disc), în scopul măririi siguranţei în exploatare unele SGBD
oferă protocoale de jurnalizare “înainte de scriere” (“write-ahead”) care forţează scrierea pe disc a
înregistrărilor din jurnal înainte de actualizarea corespunzătoare a datelor. Asemenea protocoale
evoluate asigură astfel posibilităţi de recuperare din eroare imediată, de exemplu în cazul erorii la
scrierea noii valori a unei date pe disc.
32
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
Jurnalizarea şi salvarea permit SGBD recuperarea din eroare completă şi automată prin
refacerea stării bd dinaintea erorii: după restaurarea bd cu ajutorul copiilor salvate (în cazul în care acest
lucru este necesar), refacerea actualizărilor bd se poate face, trivial, parcurgând jurnalul respectiv “de
la cap la coadă” şi refăcând corespunzător datele pentru toate tranzacţiile care se şi terminaseră; restul
tranzacţiilor sunt apoi repornite.
Puncte de verificare
Aşa cum am menţionat mai sus, pentru a mări performanţele sistemului (având în vedere
viteza mult mai scăzută a acceselor la disc în raport cu cele la memoria RAM) SGBD nu scriu pe disc
fiecare actualizare imediat, ci le grupează, folosind zone tampon relativ mari, astfel încât actualizările
sunt de fapt memorate doar în RAM şi scrise pe disc mai târziu, mai multe deodată. De exemplu, chiar în
absenţa unui protocol de jurnalizare înainte de scriere, este posibil ca sfârşitul unei tranzacţii să fie scris
în jurnal fără însă ca ultimele actualizări (poate chiar toate!) să fie şi ele scrise pe disc (acest lucru
urmând a se face ulterior, la umplerea zonei tampon corespunzătoare).
Pentru a scurta timpul necesar refacerii actualizărilor la recuperarea din erori, unele SGBD
folosesc “punctele de verificare” (“checkpoints”): acestea sunt înregistrări în jurnalele de actualizări
făcute în momente în care sistemul a forţat scrierea pe disc prealabilă a tuturor zonelor tampon din
memorie. În caz de eroare, vor trebui evident refăcute doar actualizările ulterioare ultimului punct de
verificare. Cu cât sunt mai frecvente aceste puncte de verificare, cu atât mai scurt este timpul de
refacere a bd; desigur însă că fiecare punct de verificare în parte încetineşte viteza de procesare a
tranzacţiilor. Ca atare, ele trebuie cerute sistemului de către administratorii săi în mod regulat (de obicei
la intervale fixe de timp sau imediat după terminarea unui număr fixat de tranzacţii) dar astfel încât să se
optimizeze performanţele globale ale sistemului.
Punctele de verificare permit recuperarea din eroare automată, chiar transparentă utilizatorilor,
fără a face apel la copiile de salvare ale bd afectate, aşa cum se poate observa din exemplul următor:
Exemplul 11.1
33
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
34
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
Tranzacţii
1 •
2 •
3 •
4
5
6 • axa
timpului
Desigur că aceasta implică două considerente la fel de importante: sistemul de rezervă trebuie
să aibă mereu datele cât mai recente în raport cu sistemul principal (lucru care se realizează prin
mecanisme de replicare a datelor şi jurnalelor de actualizări) şi să poată prelua rapid procesarea
tranzacţiilor de la acesta în caz de dezastru.
Utilitarul RECOVER TABLESPACE permite recuperarea din eroare a unui spaţiu tabelă,
folosind datele din catalog despre salvări, copiile disponibile, punctele de verificare şi jurnalul de
35
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
actualizări. Cataloagele menţin şi date despre punctele de verificare. Restaurarea partiţiilor unui spaţiu
tabelă se poate face şi ea în paralel. Pot fi salvate / restaurate şi fişiere index ca şi cataloagele sistem.
Pentru mărirea performanţelor, se pot face şi salvări “pe viu” (“on-line”), în timp ce utilizatorii accesează
datele respective; dacă aceştia actualizează datele în timpul salvării, acestea se zic “copii spulberate”
(“fuzzy backup”), deoarece ele nu pot fi utilizate pentru restaurarea datelor decât în conjuncţie cu
jurnalul de actualizări (ce trebuie să aducă la zi valorile datelor modificate după salvare).
Jurnalele de actualizări (care se pot menţine în două copii, pentru sporirea siguranţei)
memorează atât valorile dinaintea cât şi cele de după fiecare actualizare. Vechile jurnale pot fi arhivate (de
obicei pe benzi). Există o mulţime de date VSAM distinsă, numită “bootstrap data set”, care memorează
date despre toate jurnalele active şi arhivate, conţinutul lor şi punctele de verificare ce le conţin; ea poate fi
listată la cererea administratorului bd.
Suplimentar, există şi un utilitar REPAIR care corectează rapid datele inconsistente, pentru
ocaziile în care ori e vorba de date neimportante (exemplu, de test), sau se ştie că datele au fost foarte
puţin afectate sau atunci când nu este timp pentru recuperarea corectă din eroare; desigur că se impun
mari precauţii în acest ultim caz!
TMF realizează salvări (inclusiv “spulberate”) / restaurări (prin utilitarele BACKUP / RESTORE)
şi gestionează jurnalele de actualizări atât sistem (ale cataloagelor, vezi capitolul 16), cât şi utilizator;
acestea conţin valorile dinaintea şi de după fiecare actualizare, precum şi cele relative la punctele de
verificare (aici zise “control points”). Pentru siguranţă mărită, jurnalele sunt memorate pe alte discuri
decât bd. Recuperarea din eroare se poate face automat sau readucând datele la ultima lor stare
consistentă, sau la cea a oricărui moment consistent anterior.
“Remote Duplicate Database Facility” (RDF) este o extensie a TMF ce permite utilizatorilor să
copieze datele de pe un server aflat la distanţă, astfel încât, în cazul indisponibilităţii bruşte a vreunuia
din ele, un alt server să poată imediat prelua şi activităţile acestuia. Una din noutăţile aduse de NonStop
TM / MP este cea privind suportul pentru “overflow audit volumes”: pentru a evita oprirea tranzacţiilor
din cauza lipsei de spaţiu suplimentar pentru jurnalul de actualizări, acesta monitorizează praguri
prestabilite (implicit sau explicit, de către administratorul bd) de umplere a jurnalelor şi, la depăşirea lor,
arhivează începutul jurnalului pe un volum “de debordare” special.
şi oferă instrucţiunea RECOVER pentru recuperarea din eroare pe baza jurnalului (ce trebuie, evident,
executată doar după restaurarea manuală a fişierelor afectate!).
Utilitarele pentru exportul şi importul datelor pot însă servi şi pentru salvarea şi restaurarea
datelor; ele permit copii totale sau incrementale (pentru care există şi un utilitar de compactare similar
MERGECOPY al IBM) ale tuturor obiectelor unei bd, sau numai toate ori doar unele dintre cele ale unui
proprietar oarecare.
Jurnalele însă pot fi menţinute în dublu exemplar, simultan pe două discuri diferite, pentru
sporirea siguranţei. Pentru un jurnal, se alocă de fapt mai multe fişiere de lungime fixă ce sunt utilizate
circular (când unul se umple, sistemul trece la următorul, rescriind astfel cel mai vechi scris dintre ele).
Implicit, punctele de verificare sunt constituite doar de momentele în care se schimbă fişierul jurnal
curent cu următorul; utilizatorii pot însă specifica şi altele, suplimentare.
Comanda DISK MIRROR are ca efect şi duplicarea jurnalelor (împreună cu bd) pe un alt disc;
aceasta măreşte sensibil siguranţa şi disponibilitatea datelor (însă cu pierderile de performanţă de
rigoare). Comenzile LOAD DATABASE şi LOAD TRANSACTION sunt duale celor similare de salvare şi
realizează refacerea bd şi / sau a jurnalelor de actualizări.
Pentru a evita blocajele datorate umplerii jurnalelor de actualizări, sistemul forţează pentru
fiecare din ele un “prag al ultimei şanse”: dacă spaţiul disc scade sub acest prag, sistemul opreşte
temporar toate tranzacţiile şi invocă automat o procedură memorată sistem de salvare a jurnalului; apoi
reiniţializează jurnalul şi reia execuţia tranzacţiilor. Administratorii bd şi utilizatorii pot fixa însă praguri
proprii, la atingerea cărora sistemul poate lansa automat în execuţie o procedură memorată utilizator
care să elibereze spaţiu suplimentar disc.
Versiunea 10 oferă o facilitate originală, de neîntâlnit la nici unul dintre celelalte SGBD
analizate în lucrare, şi anume posibilitatea de a scrie “tranzacţii structurate” (“nested transactions”)
pe subtranzacţii. O subtranzacţie este delimitată de instrucţiunile BEGIN TRANSACTION şi COMMIT,
putând conţine în interior oricâte alte subtranzacţii, pe oricâte niveluri de adâncime. În general, o
asemenea structurare a tranzacţiilor poate apărea atunci când o aplicaţie are nevoie de sau provoacă
execuţia mai multor proceduri memorate şi/sau trăgaciuri, fiecare dintre acestea putând, la rândul lor,
invoca sau provoca execuţia altor proceduri memorate şi/sau tranzacţii.
De notat însă că, de fapt, sistemul nu consideră terminată nici o subtranzacţie, chiar dacă ea a
executat COMMIT, până când tranzacţia înveliş exterior a tuturor subtranzacţiilor astfel structurate nu se
termină; dacă aceasta din urmă este “desfăcută” (din orice motiv ar fi) toate tranzacţiile interioare,
inclusiv cele ce s-au terminat, sunt “desfăcute” la rândul lor.
37
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
Pentru a preveni debordarea jurnalelor, sistemul le arhivează “pe viu”, continuu: dacă s-a
specificat opţiunea WITH JOURNALING a instrucţiunii CREATE TABLE, aceasta înseamnă mutarea
înregistrărilor pentru tranzacţiile terminate din jurnalul curent într-unul arhivă; în caz contrar, aceste
înregistrări sunt pur şi simplu şterse! Jurnalele memorează atât valorile dinainte şi de după actualizări,
cât şi punctele de verificare.
38
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
4. SECURITATEA DATELOR
În foarte multe cazuri, nu toţi utilizatorii bd trebuie să aibă acces la orice date. Controlul
accesului la date este realizat de SGBD prin posibilitatea acordării de privilegii utilizatorilor autorizaţi. În
general, recunoaşterea acestora se face prin câte o pereche de tip (cont/utilizator, parolă), administratorii
bd fiind responsabili cu gestionarea privilegiilor garantate utilizatorilor autorizaţi.
Privilegii
Tipurile de privilegii oferite de diverse SGBD sunt foarte variate; în esenţă însă, ele includ
dreptul de a citi date, a scrie date, a crea noi structuri de date (exemplu: bd sau tabele într-o bd
existentă) şi dreptul de a executa anumite programe (utilitare). Privilegiile pot fi garantate implicit (de
exemplu, administratorul unei bd poate avea automat dreptul de a crea noi tabele în bd, creatorul unei
tabele să scrie şi să citească conţinutul ei etc.) sau explicit (de exemplu, administratorul unei bd poate
garanta unor utilizatori dreptul de a crea tabele, altora doar pe cel de a scrie în tabelele existente, unora
doar de a le citi, iar restului de utilizatori le poate interzice până şi citirea).
• tuturor utilizatorilor dintr-un grup (definit de administratorul bd); de exemplu, toţi angajaţii
serviciului de contabilitate al unei firme ar putea alcătui un asemenea grup; privilegiile
garantate grupului (de obicei de scriere/citire în anumite tabele şi doar de citire în altele) sunt
moştenite de toţi membri acestuia (acest tip de privilegiere grupată având, evident, două mari
avantaje: poate modela fidel organigrama firmelor şi simplifică munca administratorului bd);
Privilegiile se pot acorda în unele SGBD doar pentru porţiuni din tabele. De exemplu, orice
angajat ar putea citi datele despre colegii săi de colectiv, cu excepţia salariului (accesibil doar şefului de
colectiv), fără însă a avea acces la datele despre ceilalţi angajaţi ai firmei. SGBD relaţionale pot oferi
asemenea privilegii parţiale foarte uşor prin intermediul “punctelor de vedere” (“view”) diferite asupra
datelor.
39
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
disc. SGBD evoluate oferă chiar posibilitatea codificării folosind proceduri de criptare definite de
utilizatori.
Unele SGBD menţin în plus “dâre de verificare” (“audit trails”), jurnale în care memorează
toate activităţile din sistem (inclusiv eventualele tentative de acces neautorizat). Se pot astfel verifica
utilizatorii care au modificat (poate chiar criminal!) datele sau au încercat să violeze interdicţiile de acces.
• Cereri de la distanţă (“remote requests”): utilizatorii pot citi şi modifica date într-un server
aflat la distanţă, dar este permisă o singură instrucţiune SQL per tranzacţie şi per server (deci
o instrucţiune nu poate implica decât un server);
• Unitatea de lucru de la distanţă (“remote unit of work”): utilizatorul poate citi şi modifica
date într-un server aflat la distanţă, dar este permisă o unică tranzacţie, ce poate fi alcătuită din
oricâte instrucţiuni SQL, implicând însă doar acel server;
• Unitatea de lucru distribuit (“distributed unit of work”): utilizatorii pot citi şi scrie date în
mai multe servere per tranzacţie, cu condiţia ca orice instrucţiune SQL a tranzacţiei să facă
apel la un singur server; actualizarea datelor pe mai multe servere presupune utilizarea
protocolului terminării în două faze (vezi capitolul 13);
• Cereri distribuite (“distributed requests”): utilizatorii pot citi şi scrie date în mai multe
servere per tranzacţie; orice instrucţiune SQL a tranzacţiei poate face apel la oricâte servere;
actualizarea datelor pe mai multe servere presupune utilizarea protocolului terminării în două
faze (vezi capitolul 13); optimizarea globală (vezi capitolul 15) este necesară (în special pentru
operaţii join şi reuniune multi-server).
din sistemul de operare VMS al DEC (patru privilegii: citire, scriere, execuţie, ştergere; patru clase de
utilizatori locali: administrator sistem, proprietar obiect, grup, public; şi trei de utilizatori distribuiţi:
proprietar, grup, public).
Ierarhia utilizatorilor include trei tipuri de “roluri” (administratori sistem, ofiţeri de securitate a
datelor şi operatori sistem), plus oricâte alte niveluri inferioare de grupuri de utilizatori sau utilizatori
individuali obişnuiţi. Versiunea 10 include şi un jurnal de verificare a accesului; diverse proceduri
memorate (vezi capitolul 17) permit ofiţerilor de securitate (singurii care au acces la asemenea jurnale!)
să urmărească orice încercare de acces, a oricui, la orice obiect.
Majoritatea bd gestionate de Ingres sunt publice; se pot însă defini bd private, la care au acces
doar proprietarul bd, administratorul sistem şi eventualii utilizatori cărora le-au fost acordate privilegii de
proprietar (administratorul sistem neavând acest drept). Sunt menţinute şi jurnale de control al accesului,
deşi acestea sunt mai degrabă o formă primitivă de jurnale de actualizare (care nu există) în care însă
nu sunt memorate instrucţiunile şi/sau valorile modificate, ci doar data şi ora începerii tranzacţiei,
identificatorul acesteia, numele utilizatorului, tipul de operaţii efectuate (selecţie, inserţie, actualizare,
ştergere) şi identificatorul fiecărei tabele accesate.
41
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
5. IMPUNEREA CONSTRÂNGERILOR DE
INTEGRITATE
Menţinerea integrităţii datelor este, de departe, cea mai importantă sarcină permanentă a
oricărui SGBD. Ca atare, sunt oferite diverse mecanisme de verificare a consistenţei datelor şi de
impunere a constrângerilor de integritate. Ne vom focaliza din nou atenţia numai asupra celor mai des
întâlnite asemenea mecanisme.
Cea mai simplă verificare cu putinţă este cea de încadrare a tuturor valorilor pe care le au
datele fiecărei coloane a oricărei tabele dintr-o bd într-un interval de valori (explicit precizat de
administratorul bd pentru datele fundamentale sau implicit, pentru cele derivate). SGBD relaţionale oferă
în acest scop cel puţin două mecanisme suport pentru integritatea domeniilor (de valori) şi integritatea
referinţelor.
Integritatea referinţelor
Ca efect al “propagării cheilor”, al dependenţelor de incluziune sau al constrângerilor de tip
sisteme de reprezentanţi (vezi prima parte a lucrări), multe tabele ale unei bd relaţionale conţin coloane
de pointeri spre alte tabele sau chiar spre tabela din care fac parte (iar cum pointerii sunt folosiţi şi de
SGBD non-relaţionale, problema aceasta este mult mai generală). Valorile dintr-o asemenea coloană
(numită şi “cheie străină”) trebuie întotdeauna să fie strict printre valorile unei alte coloane ce face parte
dintr-o cheie a unei tabele. De exemplu, coloana Judeţ dintr-o tabelă de Localităţi ar trebui să aibă
mereu valori din coloana CodJudeţ, cheie în tabela de Judeţe. Acest tip de constrângere se numeşte
integritatea referinţelor.
42
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
Impunerea integrităţii referinţelor nu este complet trivială, nici măcar în cazul actualizării valorii
pointerilor. Astfel, dacă la inserţia unui nou pointer sau la modificarea valorii unuia existent cu o valoare
inexistentă în coloana cheie referită de pointer există soluţia simplă a respingerii actualizării respective,
un SGBD evoluat ar trebui desigur să întrebe utilizatorul dacă nu cumva doreşte să insereze un nou
rând în tabela referită, având noua valoare drept cheie, sau poate doreşte să modifice una dintre valorile
cheii referite în noua valoare (în loc de respingerea actualizării, care de multe ori obligă utilizatorul să
deschidă şi tabela referită în mod actualizare date, să insereze sau modifice în ea pentru a adăuga noua
valoare printre chei, înainte de a se reîntoarce în tabela iniţială pentru a relua operaţia respinsă). Iar
dacă modificarea valorilor cheii referite poate conduce la complicaţii (căci s-ar putea cere, din greşeală,
modificarea într-o altă valoare deja existentă a cheii, tentativă ce trebuie respinsă desigur), măcar
inserarea unei noi chei în tabela referită este o facilitate extrem de simplu de implementat şi care
economiseşte mult timp utilizator.
În cazul actualizării valorilor unei chei referite (de una sau mai multe coloane) prin ştergerea
unei valori existente, în coloanele ce referă cheia respectivă pot apărea probleme de implementare şi
mai mari. Astfel, dacă ştergerea ar fi pur şi simplu permisă (ceea ce se întâmplă încă, din păcate, în
destule SGBD relaţionale!) toţi pointerii care refereau acea valoare a cheii rămân “în aer”, drept pentru
care sunt referiţi ca pointeri “încurcând lumea” (“dangling pointers”). Desigur că cea mai simplă
soluţie este de a interzice orice asemenea ştergere. Într-o asemenea implementare însă, dacă ştergerea
este uneori chiar necesară, utilizatorul va trebui întâi să şteargă toate referinţele la acea valoare a cheii.
S-ar putea deci oferi utilizatorilor posibilitatea de a opta pentru ştergerea automată atât a valorii cheii
referite, cât şi a tuturor referinţelor la ea (sau înlocuirea acestora cu referinţe la “obiectul necunoscut”
corespunzător). Poate nu chiar atât de evident, însă cu atât mai important de avut în vedere în
rezolvarea acestei delicate probleme de implementare a SGBD, este faptul că şi rândurile ce conţin
pointeri ce urmează a fi astfel şterşi pot fi, la rândul lor, referiţi de alte chei străine, pe oricâte astfel de
niveluri de recursivitate!
Mai mult, într-un SGBD ce ar suporta printre constrângeri pe cele de tip sisteme de
reprezentanţi (SR), cum ar fi unul construit pe baza MMED (vezi [253] şi prima parte a lucrării), s-ar
putea oferi utilizatorilor şi facilitatea de a reorganiza clasele de echivalenţă automat, inclusiv prin
splitarea unei clase în mai multe noi clase (mai fine) sau, dual, prin contopirea mai multor clase într-una
singură. Evident că asemenea operaţii ridică noi probleme de implementare legate tot de faptul că, în
asemenea situaţii, ar fi necesară şi modificarea corespunzătoare a tuturor pointerilor ce referă cheile
implicate (iar dacă pentru contopiri acest lucru se poate face complet automat, transparent utilizatorului,
în cazul splitărilor este desigur nevoie de consultarea utilizatorului pentru fiecare pointer în parte).
Trăgaciuri
Oricâte alte mecanisme de verificare şi impunere a constrângerilor de integritate primitive ar
mai oferi un SGBD, el tot trebuie să permită (pentru a putea garanta deplina consistenţă a bd) şi
impunerea de constrângeri bazate pe predicate oarecare, ad-hoc. Acest lucru este oferit de majoritatea
SGBD sub forma procedurilor de tip “trăgaci” (“declanşator”). Un asemenea trăgaci (“trigger”) este o
procedură utilizator (scrisă pentru implementarea unei sau mai multor constrângeri predicative oarecare)
căreia i se asociază la definire momentul în care execuţia ei trebuie declanşată automat de sistem.
Implementările uzuale specifică pentru aceasta coloana (sau coloanele) în care, dacă se
încearcă scrierea unei/unor valori, SGBD “apasă” automat pe “trăgaci”; dacă trăgaciul constată că noile
valori nu violează constrângerea pe care el o impune, SGBD va permite scrierea noilor valori; în caz
contrar, scrierea este respinsă, iar SGBD obligat probabil să-şi “desfacă” tranzacţia care a atentat astfel
la integritatea bd.
43
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
bancar în altul), trebuie scăzută suma transferată din contul debitor (gestionat de un SGBD1) şi crescută
corespunzător suma în contul creditat la distanţă (care este gestionat de un SGBD2). Protocolul în două
faze a terminării trebuie să garanteze faptul că cele două SGBD ori au efectuat ambele aceste operaţii,
ori nici una dintre ele.
Nevoia unui asemenea protocol poate apărea atât în cadrul unei unice platforme (rulând două
sau mai multe SGBD concurente, vezi cazul platformelor paralele, dar nu doar al acestora), cât şi pentru
arhitecturi de platforme interconectate (la distanţă sau local) ale căror SGBD trebuie să coopereze.
Particularităţile bd distribuite complică însă mult situaţia şi impun rafinări ale acestui protocol. Pentru a le
înţelege, să analizăm următoarele două exemple:
Exemplul 13.1
Pe lângă complicaţiile ce pot apărea ca urmare a erorilor de transmisie în reţele, sunt desigur
posibile oricând şi căderi de sistem ale serverelor locale, ce antrenează şi ele costuri suplimentare
pentru menţinerea integrităţii datelor şi tranzacţiilor.
44
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
Exemplul 13.2
Drept urmare, pentru reducerea traficului de mesaje în reţea, au fost aduse două îmbunătăţiri
majore acestui protocol: “terminarea presupusă” (“presumed commit”) şi “abortarea presupusă”
(“presumed abort”) a tranzacţiilor. În exemplul 13.1 de mai sus, atunci când participanţii confirmă
coordonatorului posibilitatea terminării tranzacţiei, ei îşi înscriu în jurnal instrucţiunea de terminare
presupusă şi pot astfel scoate toate eventualele lacăte puse de tranzacţie; la rândul său, la primirea
tuturor confirmărilor, coordonatorul scrie şi el în jurnal instrucţiunea de terminare presupusă, iar dacă nu
mai poate să transmită COMMIT vreunui participant, nici nu mai încearcă acest lucru până la restabilirea
comunicaţiilor cu acesta (de care va afla, la un moment dat, ori când va fi reapelat de acel participant, ori
când va mai încerca să-l contacteze pentru o altă tranzacţie).
45
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
Trăgaciurile sunt proceduri memorate speciale (vezi capitolul 17) scrise în limbajul de
programare extins PL/SQL, care sunt ataşate tabelelor şi se execută automat exact înainte de sau după
un eveniment oarecare (exemplu, execuţia unei instrucţiuni INSERT, UPDATE sau DELETE asupra
tabelei), o dată per eveniment sau pentru fiecare linie procesată în cadrul evenimentului. Fiecărei tabele i
se pot asocia oricâte trăgaciuri, inclusiv incluse unul în altul, ce vor fi executate de sistem într-o ordine
arbitrară. Administratorii bd pot suspenda temporar execuţia automată a trăgaciurilor (din considerente
de performanţă sau de indisponibilitate temporară a unor date).
46
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
Indexurile pot fi automat creaţi de SGBD (pentru cheile tabelelor sau pentru a mări viteza de
procesare a interogărilor) sau creaţi la cererea administratorilor sau utilizatorilor bd. Similar, actualizarea
lor (pentru a reflecta actualizările datelor indexate) se face automat, transparent utilizatorilor, de marea
majoritate a SGBD evoluate, deşi şi acesta poate include comenzi de reindexare la îndemâna
utilizatorilor. Ştergerea indexurilor are acelaşi regim: automată, pentru indexurile temporar create de
SGBD ori pentru tabelele şterse, sau manuală.
La limită, desigur, se pot crea indexuri pentru toate coloanele tuturor tabelelor. Trebuie însă
avut mereu în vedere faptul că fiecare index ocupă spaţiu disc şi consumă timp atât pentru crearea, cât
şi pentru actualizarea sa. Implicit, SGBD moderne creează automat indexuri pentru fiecare “cheie”
(coloană sau mulţime de coloane minimal injectivă; vezi prima parte a lucrării) în parte. Asemenea
indexuri sunt zise unice, spre deosebire de cele non-cheie (care admit deci duplicate printre valorile
indexate) care se zic neunice.
Unele SGBD oferă şi indexuri ciorchine (“cluster”) care asigură performanţe sensibil mărite
pentru unele operaţii (exemplu: găsirea tuturor articolelor ştiinţifice publicate pe o temă fixată în ordinea
inversă a publicării lor). Aceasta implică ordonarea liniilor din tabelă în ordinea indexului pentru fiecare
ciorchine al tabelei (ciorchinele fiind o pagină disc în care sunt memorate mai multe linii).
Cel mai rapid acces la date s-ar obţine dacă am putea indica SGBD adresa la care se găseşte
pe disc fiecare dintre tuplii pe care dorim să îi accesăm (aşa-zisul identificator al tuplului, prescurtat
IDT). Desigur că acest lucru este aproape imposibil pentru un volum mare al datelor, care se şi modifică
continuu prin inserarea şi ştergerea de noi linii (articole). Există foarte multe tehnici posibile de
implementare a indexurilor; cele mai uzuale dintre ele sunt însă tabelele “talmeş-balmeş” (“hash”), care
încearcă doar să calculeze IDT şi arborii B+, care preferă memorarea tuturor IDT.
În locul IDT al tuplului dorit, utilizatorul poate furniza sistemului doar o cheie de căutare
“talmeş-balmeş” a acestuia, pe baza căreia SGBD calculează apoi adresa corespunzătoare. Unică
per tabelă, această cheie este constituită din una sau multe coloane ale tabelei (exemplu, pentru o
tabelă de angajaţi: numărul de identificare sau numele şi prenumele angajaţilor). SGBD foloseşte o
rutină (subprogram) de calcul al unei adrese de memorare unice pentru orice linie a tabelei pe baza
valorilor acestei chei de căutare. În SGBD relaţionale, cheia de căutare implicită este cheia (primară a)
tabelei.
Există mulţi algoritmi pentru transformarea valorilor cheii de căutare în adrese. Cel mai adesea
folosiţi sunt cei de tip aritmetic, ce au avantajul vitezei foarte mari de calcul (câteva instrucţiuni aritmetice
cu operanzi deja în RAM fiind suficiente); de exemplu, se împarte valoarea cheii (interpretată ca un
număr întreg) la un număr prim suficient de mare, iar restul obţinut este considerat a fi adresa dorită.
Astfel, valoarea cheii de căutare poate fi direct şi rapid transformată de SGBD în IDT corespunzător.
47
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
Obţinerea IDT însă (care trebuie să fie unic pentru orice tuplu!) nu este garantabilă de către
algoritmii “talmeş-balmeş”. Desigur că este posibilă coliziunea unor chei, adică apariţia de sinonime
(i.e. valori ale cheii pentru care rutina de transformare calculează o aceeaşi valoare). De exemplu, dacă
o companie are 50 de angajaţi, identificaţi de numere de la 1 la 50 memorate de o cheie “talmeş-balmeş”
ID_Ang definită, pentru economie de spaţiu, ca un număr binar pe 2 octeţi (putând deci identifica 65.536
posibili angajaţi), iar rutina alege drept număr prim pe 47, atunci cheile 1 şi 48, respectiv 2 şi 49, ca şi 3
şi 50 vor fi sinonime, producând coliziuni în calculul IDT.
Cea mai frecventă metodă de rezolvare a coliziunilor este gruparea fiecărui grup de sinonime
în câte o “găleată” (“bucket”): ori se alocă spaţiu pentru o singură găleată mare, în care sunt memorate
toate sinonimele înlănţuite (pe clase de echivalenţă); ori se alocă spaţiu fix pentru fiecare sinonim, iar
când o asemenea găleată se umple, ori se măresc toate găleţile (ceea ce ar putea conduce la mari
pierderi de spaţiu, căci alte găleţi pot rămâne aproape goale), ori tuplii care ar da pe dinafară sunt
memoraţi înlănţuit într-o unică găleată suplimentară (ca în prima variantă).
În oricare dintre implementări însă, în caz de coliziune, SGBD trebuie să caute secvenţial în
găleata respectivă tuplul dorit (pe baza valorii cheii de căutare). Oricum, accesul de tip “talmeş-balmeş”
este util doar în anumite cazuri particulare, pentru acces aleator la câte un tuplu răzleţ; pentru accesul
implicând intervale de valori ale unor chei ordonate sau pentru aplicaţii ce solicită sortarea răspunsului
(crescător sau descrescător) după valoarea unei chei, arborii B+ sunt mult mai indicaţi. Totuşi, destule
SGBD încă mai oferă şi chei “talmeş-balmeş”.
Arbori B+
Arborii B+ sunt structuri de date arborescente special proiectate pentru implementarea
indexurilor în bd. Fişierul index propriu-zis este partajat între frunzele arborilor; fiecare frunză conţine mai
multe perechi formate dintr-o valoare a cheii indexate şi IDT corespunzător, ordonate (de obicei
crescător) după valoarea cheilor.
Celelalte noduri (interne) ale arborelui B+, inclusiv rădăcina, sunt constituite de pagini (blocuri);
o asemenea pagină conţine întotdeauna maxim k valori ale cheii indexate, intercalate printre k+1 pointeri
către nodurile fii ale paginii respective (unde naturalul k este fixat prin calcule de optimizare a vitezei de
acces la date prin arbore, ţinând cont atât de minimizarea spaţiului disc ocupat de index, cât mai ales de
timpul necesar reorganizării arborelui atunci când se depăşeşte capacitatea de memorare a unei pagini,
ca şi de timpul necesar reechilibrării arborelui în urma inserării şi ştergerii de chei indexate).
Figura 14.1 oferă un exemplu de asemenea arbore B+; ‘*’ din frunze figurează IDT-uri; se
observă că toate nodurile interne conţin succesiuni de tip (pointer1, cheie1, pointer2, cheie2, ...,
pointerk+1), unde pointerii sunt figuraţi prin ‘*’ iar semnificaţia oricărui pointerj este următoarea: nodul fiu
indicat de acest pointer este ori frunza ce memorează toate valorile cheii indexate cuprinse în intervalul
mărginit de cheiej-1 şi cheiej+1, ori o altă pagină conţinând valori ale cheii aflate în acelaşi interval. Dacă
pointerul este primul sau ultimul din nod, atunci cheiej-1 respectiv cheiej+1 sunt considerate a fi valorile
cheii corespunzătoare din pagina tată a celei curente (adică cea aflată imediat la stânga, respectiv
imediat la dreapta pointerului care indică pagina curentă; în cazul rădăcinii, în mod natural, la stânga
primului pointer se consideră a fi valoarea minimă posibilă a cheii, iar la dreapta ultimului pointer, dual,
se consideră valoarea maximă posibilă a cheii).
48
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
* 30 * 60 * pagina rădicină
*10 * 18 * * 36 * 43 * 51 * * 72 * 85 *
2*4*7*8* 11 * 15 * 18 * 19 * 30 * 31 * 35 * 37 * 38 * 41 * 44 * 45 * 51 * ..
Pe lângă un acces suficient de rapid la orice tuplu, fără complicaţii de tip coliziune, arborii B+
sunt extrem de eficienţi pentru accesul implicând intervale de valori ale unor chei ordonate sau pentru
aplicaţii ce solicită sortarea răspunsului (crescător sau descrescător) după valoarea unei chei astfel
indexate. Mai mult, el permite furnizarea răspunsului la interogările ce implică doar coloane indexate în
mod simplu, direct din fişierul index, fără a mai fi necesară consultarea tabelei corespunzătoare (acelaşi
lucru e valabil şi pentru joinuri, vezi capitolul 15).
Această dublă indirectare are avantajul că, atât timp cât un tuplu este memorat într-o aceeaşi
pagină, IDT-ul său nu se modifică (deci nici indexul său nu trebuie modificat, fie el tabelă “talmeş-
balmeş”, fie arbore B+), chiar dacă poziţia tuplului în pagină se schimbă. Pe lângă economia de timp
astfel realizată, aceasta permite SGBD reorganizarea internă a paginilor memorând tuplii (pentru
recompactarea sau sortarea lor) fără afectarea indexurilor.
49
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
Cea mai interesantă inovaţie în domeniul fişierelor index se referă însă la “indexurile
alternative” (orice index, cu excepţia celor pentru cheile primare ale tabelelor): acestea memorează nu
doar valorile cheii respective, ci şi pe cele ale cheii primare corespunzătoare! Astfel, desigur, răspunsul
la foarte multe interogări poate fi furnizat doar din indexuri, fără accesarea tabelelor propriu-zise.
50
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
7. OPTIMIZAREA PROCESĂRII ŞI
ACCESULUI LA DATE
De cele mai multe ori există mai multe posibilităţi de a accesa datele dorite dintr-o bd. Orice
SGBD care se respectă are încorporat, în consecinţă, un optimizator care o alege pe cea mai bună, la
orice moment dat, în funcţie de criteriul dorit. Strategia de acces la date aleasă de optimizator este cel
mai adesea decisivă în obţinerea de performanţe cât mai bune. Ca atare, toţi furnizorii de SGBD
cheltuiesc enorm pentru perfecţionarea optimizatoarelor cu care îşi dotează produsele.
Cea mai costisitoare operaţie cu putinţă asupra datelor este, de departe, join-ul (vezi prima
parte a lucrării). Deşi au fost proiectate foarte multe strategii de implementare a sa în diverse condiţii,
cercetătorii în domeniu încă mai caută noi soluţii, mai bune măcar în anumite circumstanţe. Este
obligatorie, ca atare, începerea acestui capitol cu studiul optimizării join-ului.
Mai general, orice acces la date (nu doar cel pentru calculul unui join sau a unei expresii de
algebră relaţională oarecare) poate fi uneori optimizat. Principalele două tipuri existente de asemenea
optimizări (pe care le vom studia, la sfârşitul acestui capitol în cazul SGBD relaţionale, care le-am
introdus şi perfecţionat iterativ) sunt bazate pe reguli, respectiv bazate pe costuri.
Dacă n şi m sunt, respectiv, numărul liniilor din cele două tabele operand, este evident că
acest algoritm este costisitor, complexitatea sa fiind proporţională cu n*m. Această metodă de calcul al
joinului este, ca atare foarte scumpă dacă tabelele sunt mari; pentru tabele mici însă sau chiar în cazul
în care ele sunt mari dar există un index pe coloana join din cea de-a doua tabelă, ea poate fi mai bună
decât orice altă implementare.
Evident că astfel pot fi economisite foarte multe accese la a doua tabelă; este trivial faptul că,
păstrând notaţiile introduse în secţiunea anterioară, acest algoritm, numit “sort/reuniune”
(“sort/merge”), are complexitatea proporţională cu n+m. Deşi aparent el este, ca atare, întotdeauna mai
bun decât primul (n+m < n*m, ∀ n,m naturali!), nu trebuie însă uitat că acest algoritm presupune
sortarea ambelor coloane de join. Dacă ele sunt deja sortate, această implementare este întotdeauna
preferată; în anumite condiţii, chiar atunci când ele nu sunt sortate dar există câte un index pentru
fiecare, ea rămâne cea mai bună soluţie.
Dacă însă cele două coloane nu sunt sortate, atunci SGBD trebuie să le sorteze în prealabil şi
acest cost suplimentar poate face această metodă mai scumpă decât altele. În cazul tabelelor mari în
care reuşesc multe comparaţii (i.e. sunt găsite multe egalităţi şi, deci, rezultatul joinului va avea multe
linii), “sort/reuniune” rămâne însă cea mai bună, chiar dacă cele două coloane trebuie întâi sortate.
De remarcat că fiecare tuplu din cele două tabele operand iniţiale este citit doar o singură dată,
ca în metoda "sort/reuniune". Desigur că se adaugă costul operaţiilor intermediare suplimentare
("sort/reuniune" cu indexul şi sortarea tabelei intermediare), dar metoda devine cea mai bună pentru
tabele mari cu multe duplicate în coloanele pe care se cere join-ul.
52
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
Pentru aceasta, se proiectează întâi una din tabele, de la locaţia A (de regulă, cea mai mică
dintre ele, dacă nu intervin alte considerente, vezi secţiunea 15.6) pe coloana join, împreună cu IDT
(adresa tuplilor respectivi); tabela cu doar două coloane rezultat al proiecţiei este mutată pe celălalt
server B, unde se face un prim join între ea şi cea de-a doua tabelă; astfel sunt eliminate liniile ce nu
trebuie transmise (căci nu iau parte efectiv la join). Se poate cere acum transmiterea de la A la B doar a
acelor linii care sunt necesare, folosind IDT al acestora; în final, se poate calcula pe A join-ul cerut.
Este evident faptul că reducerea costurilor de transfer a datelor astfel obţinută poate fi
considerabilă, în special pentru tabele mari.
Deşi nu s-a putut găsi nici un algoritm general de optimizare a oricărei expresii de algebră
relaţională, literatura de specialitate conţine atât sugestii utile generale, cât şi un algoritm de optimizare
care este folosit, cu sau fără alte îmbunătăţiri minore, de marea majoritate a SGBD pentru evaluarea
expresiilor SPJ. Strategiile generale de optimizare includ:
• efectuarea selecţiilor cât mai devreme cu putinţă (pentru eliminarea tuplilor ce nu vor mai
participa în evaluarea în continuare a expresiei);
• combinarea proiecţiilor cu orice operaţie binară adiacentă (eliminarea unor coloane se poate
face simultan cu citirea tabelei respective pentru efectuarea unei alte operaţii);
• combinarea produselor carteziene cu acele selecţii adiacente care le pot transforma în join
(dacă un produs cartezian este argumentul unei selecţii ce conţine “şi”-uri logice de comparaţii
între coloanele operanzilor produsului, acesta se poate înlocui cu un join; de notat că, aşa cum
se poate uşor demonstra, un produs cartezian este întotdeauna mai scump decât orice join
între operanzii săi; merită semnalat aici de asemenea, că orice comparaţie a selecţiei ce nu
implică nici o coloană a vreunuia din cei doi operanzi ai produsului cartezian poate fi mutată
înaintea produsului, ceea ce este preferabil chiar transformării acestuia în join!).
1. Transformă orice conjuncţie de selecţii asupra unei expresii într-o cascadă de selecţii (asupra
expresiei respective).
2. Mută orice selecţie cât mai jos posibil în arbore (spre frunze).
3. Elimină proiecţiile inutile şi împinge toate proiecţiile cât mai jos posibil în arbore (eventual desfăcând
unele din ele în două, dacă se poate, ori de câte ori proiecţia nedesfăcută nu mai poate coborî, dar
măcar una din componentele sale ar mai putea-o face).
53
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
4. Combină cascadele de selecţii şi proiecţii într-o singură selecţie, o singură proiecţie sau o selecţie
urmată de o proiecţie.
5. Partiţionează nodurile arborelui astfel rezultat în grupuri, după cum urmează: fiecare nod interior
reprezentând un operator binar (produs, reuniune sau diferenţă) formează un grup ce mai conţine
toate nodurile strămoşi adiacente reprezentând operaţii unare (selecţii sau proiecţii), precum şi orice
lanţuri de descendenţi unari ce se termină cu o frunză, cu excepţia cazului în care operatorul binar e
un produs cartezian ce nu este urmat de nici o selecţie cu care să se poată combina pentru a se
transforma în join.
6. Evaluează grupurile independent unul de altul, cu singura restricţie că nici un grup nu poate fi evaluat
înainte de vreun grup descendent de-al său.
Exemplul 15.1
select *
from T
where C1 = k1
and C2 = k2
Să presupunem că SGBD dispune de câte un index pentru fiecare din cele două
coloane; dacă optimizatorul ar folosi doar unul dintre aceştia, de exemplu cel
pentru C1, ar putea selecta rapid doar toate liniile T pentru care C1 are valoarea
k1; multe din acestea însă nu satisfac probabil predicatul de selecţie, neavând
valoarea k2 în coloana C2 (şi deci au fost inutil selectate, trebuind a fi eliminate
din răspuns într-un al doilea pas). Folosirea concomitentă a celui de-al doilea
index ar putea, evident, optimiza implementarea acestei selecţii.
Procesarea “index AND” pe care o schiţăm în continuare presupune doi arbori B+ drept
indexuri: optimizatorul scanează cele două indexuri, selectând din fiecare doar IDT ai tuplilor ce satisfac
comparaţia respectivă (pentru exemplu de mai sus, cei pentru care cheile index au valorile k1, respectiv
k2); cei doi vectori (i.e. tabele unicoloană) de IDT astfel rezultaţi sunt apoi intersectaţi, obţinându-se în
acest mod un vector ce conţine doar IDT ai răspunsului cerut; pe baza sa, sunt în final citiţi din tabela T
doar tuplii corespunzători. Evident că procesarea “index OR” este similară: dacă predicatul selecţiei din
exemplul 15.1 ar fi “or” (în loc de “and”), este suficientă înlocuirea intersecţiei cu reuniunea vectorilor de
IDT.
54
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
Au fost propuse mai multe asemenea seturi ad-hoc de reguli, fără însă a se putea demonstra
pentru vreunul eficienţa sa în general sau măcar în raport cu vreun alt set de asemenea reguli. Mai mult,
există puternice indicii că aşa ceva nici nu se poate demonstra vreodată. În plus, orice asemenea set
presupune cunoştinţe de specialitate din partea utilizatorilor (ca să poată formula interogări optimizabile)
iar orice modificare într-un set de reguli necesită şi modificarea unor tranzacţii (deja scrise, testate şi
memorate pentru uzul curent) pentru a beneficia de noile optimizări posibile. Toate aceste considerente
fac ca SGBD evoluate să prefere optimizarea bazată pe costuri.
Statisticile despre date, fiind meta-date, sunt memorate în cataloage (vezi capitolul 16).
Actualizarea lor este, în sine, o problemă, căci ar micşora sensibil performanţele sistemului dacă ar fi
făcută la fiecare actualizare a datelor implicate. Ca atare, ea se face de către programe utilitare
specializate la intervale mai mari de timp, de preferinţă când încărcarea sistemului este minimă. Pentru
tabelele foarte mari şi cu multe indexuri ea se poate face, opţional, doar pe baza unui eşantion aleator al
tuplilor tabelei (ce poate fi precizat implicit, de sistem, sau explicit, de către administratorul bd).
55
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
Exemplul 15.2
Desigur că, fie şi numai dpdv al cardinalităţii, decizia nu este uşoară: chiar dacă,
evident, a doua soluţie poate fi eliminată ca fiind cea mai proastă întotdeauna, este greu
de decis între prima şi a treia! Astfel, dacă rezultatul ar avea tot 100.000 linii, cele două
soluţii sunt aproape la fel de costisitoare (prima probabil puţin mai ieftină, căci, în
general, rezultatul unui join are mai multe coloane decât fiecare operand în parte); dacă
el este mai mic, a treia variantă e preferabilă; dacă el este mai mare, prima variantă este
preferabilă!
Dacă însă se iau în calcul şi costurile transmisiei, lucrurile se complică şi mai mult, fiind
posibilă răsturnarea clasamentelor de mai sus!
Un bun optimizator însă va lua în considerare mulţi alţi factori, printre care:
56
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
• alte costuri (de exemplu, dacă timpul de răspuns nu este critic şi dimpotrivă, tarifele
de comunicaţie sunt mult mai avantajoase în anumite perioade de timp ale zilei, s-ar putea ca cea
mai bună soluţie pentru exemplul de mai sus să fie a doua!).
Toate aceste considerente, care implică mult mai multe meta-date non-locale decât locale,
depăşesc cu mult capacităţile optimizatoarelor locale clasice şi impun considerarea unor optimizatoare
globale, capabile să menţină statistici globale şi să acceseze statisticile oricărui server participant.
Optimizarea în DB2
Optimizatorul DB2 al IBM, care a pornit de la prototipul System R, este considerat punctul
forte al acestui SGBD. De exemplu, implementarea hibridă a joinului a fost proiectată pentru şi utilizată
prima dată în DB2; în plus, el suportă “index AND” şi “index OR”, ca şi “buclă în buclă” şi “sort/reuniune”.
Mai mult, pentru a-şi ajuta optimizatorul, DB2 calculează automat “închiderea tranzitivă a joinului”: de
exemplu, pentru joinul exprimat în SQL prin:
select *
from Ta, Tb, Tc
where Ta.C1 = Tb.C2
and Tb.C2 = Tc.C3
el adaugă automat:
and Ta.C1 = Tc.C3
Utilizatorii care doresc să afle diversele variante avute în vedere de optimizator pentru
evaluarea unei interogări, precum şi strategia aleasă în cele din urmă (fără ca interpretorul să şi
evalueze interogarea, pentru a economisi timp!), pot invoca instrucţiunea EXPLAIN; efectul ei este doar
memorarea datelor luate în calcul de optimizator, ca şi a rezultatului deciziei acestuia într-o tabelă
PLAN_TABLE (al cărui conţinut, desigur, poate fi apoi interogat şi a cărui structură poate fi controlată şi
ea de utilizator, prin eliminarea unor câmpuri în cazul în care nu toate detaliile interesează).
Pentru optimizarea în bd distribuite, DB2 oferă mai multe facilităţi, din care se disting
evidenţierea în jurnale a activităţilor iniţiate la distanţă, mecanismele de citire şi transmisie a datelor în
blocuri mari (până la 32 pagini cu o singură operaţie de I/O) şi execuţia SQL static (vezi capitolul 17) de
la distanţă.
57
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
Instrucţiunea CONTROL TABLE, de exemplu, poate chiar impune calea de acces dorită de
utilizator (prin specificarea unui index obligatoriu).
Citirea blocurilor mari de date cu o singură instrucţiune de I/O (aici referită ca “sequential
block buffering”) permite accesul la 56K deodată; mai mult însă, operaţiile de I/O cu discul pot fi nu
doar fizice, ci şi virtuale, pentru simplificarea sarcinii etajelor superioare ale SGBD: citirea fizică poate fi
însoţită de selecţii, proiecţii şi agregări GROUP BY ale datelor, ce împing astfel aceşti operatori
relaţionali chiar în frunzele arborilor de evaluare optimizată a interogărilor!
Optimizarea în Oracle
Oracle mai suportă încă optimizarea bazată pe reguli, deşi s-a anunţat că următoarele versiuni
vor renunţa la ea în favoarea optimizării exclusiv bazată pe costuri. Statisticile pot fi şi aici exacte sau
aproximative; instrucţiunea EXPLAIN este şi ea oferită. Utilizatorii pot influenţa deciziile optimizatorului,
nu doar indicând o cale de acces, ci chiar o anume implementare a joinului, sau scopul principal al
optimizării (exemplu, viteza găsirii primelor linii sau a tuturor liniilor răspunsului).
SQL Server este şi el capabil de aplatizarea interogărilor; mai mult, el poate calcula joinuri
multitabelă (implicând însă maxim 4 tabele; un join de şase tabele, de exemplu, va fi calculat totuşi în
doar doi paşi în loc de cinci); din păcate însă el nu calculează automat închiderea tranzitivă a joinului,
aceasta rămânând în sarcina utilizatorului. Joinul este implementat doar “buclă în buclă”!
Optimizarea în CA-OpenIngres
Optimizatorul CA-OpenIngres se bazează tot pe date statistice (exacte sau aproximative) şi
poate fi influenţat de utilizatori, care pot vizualiza planurile de optimizare şi strategiile de acces la date
alese automat. Pentru datele cu distribuţie neuniformă, el poate menţine statistici pentru până la 250
valori distincte ale unei chei. Interogările distribuite sunt optimizate şi prin considerarea costurilor de
transmisie şi a performanţelor procesor ale serverelor implicate. Joinul poate fi implementat şi “buclă în
buclă” şi “sort/reuniune”; este implementată şi aplatizarea interogărilor.
58
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
8. CATALOAGE DE META-DATE
Un catalog este un fişier sistem memorând meta-date (i.e. date despre datele memorate de
bd). De exemplu, un catalog este necesar oricărui SGBD relaţional pentru a memora date despre
tabelele oricărei bd gestionate: nume, sinonime, data ultimei modificări, dimensiuni etc. Alte cataloage
sunt necesare pentru memorarea tuturor utilizatorilor autorizaţi ai fiecărei bd, precum şi a privilegiilor ce
le sunt garantate.
Cataloagele sunt automat create şi gestionate de SGBD, care are permanent nevoie să le
consulte (de exemplu, pentru a determina dacă o tabelă există sau nu, dacă un utilizator este îndreptăţit
la un anumit tip de acces într-o tabelă etc.). Optimizatoarele bazate pe costuri (vezi capitolul 15) au
nevoie de memorarea şi ţinerea permanentă la zi a unor meta-date statistice suplimentare.
Pe lângă meta-datele deja pomenite, cataloagele mai conţin informaţii despre constrângerile
de integritate, punctele de vedere utilizator asupra datelor (“views”), trăgaciuri, tranzacţiile memorate,
paginile disc de memorare a datelor, salvări, jurnale de actualizări, de verificare, de protecţie la viruşi etc.
Unele SGBD distribuite menţin în plus meta-date despre serverele SGBD cu care sunt interconectate
(nume, locaţie etc.).
Accesul în citire este adesea cel mai important: doar cu ajutorul meta-datelor se poate realiza
o bună administrare a bd, îmbunătăţirea performanţelor sistemului în condiţii locale şi/sau particulare de
exploatare, ca şi o corectă şi optimă proiectare şi programare a bd (de exemplu, cea mai bună
documentaţie despre structura unei tabele sau despre detaliile unui trăgaci rămâne cea memorată în
cataloagele SGBD!).
Desigur însă că, în esenţă, conţinutul cataloagelor este destinat a fi actualizat în special
automat, transparent utilizatorilor. Chiar atunci când se permite scrierea de către utilizatori a meta-
datelor, SGBD preferă, ori de câte ori acest lucru este posibil, să interfaţeze cataloagele cu tranzacţii
care să împiedice de fapt accesul direct în fişierele catalog, chiar dacă scrierea meta-datelor necesită
privilegii speciale, tocmai datorită riscului foarte mare de a greşi (e omenesc!) cu consecinţe prea
adesea incalculabile pentru integritatea bd gestionate.
59
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
Cum azi un asemenea lucru este practic posibil de realizat doar foarte rar, datorită
heterogenităţii serverelor, următoarea soluţie avută în vedere în bd distribuite a fost cea a menţinerii unui
catalog universal, care conţine meta-date şi date statistice despre toate tabelele din gestiunea fiecărui
server. Acesta permite oricărui SGBD distribuit să optimizeze accesul la date în orice moment, indiferent
de distribuţia lor.
Desigur că memorarea acestui catalog universal doar pe un singur server ar fi mult prea
riscantă (în cazul căderilor de sistem sau izolării temporare a serverului implicat) şi neperformantă (căci
ar încetini mult optimizatoarele celorlalte servere); de aceea, în implementările evoluate, el este replicat
pe toate serverele.
Ar merita amintit în acest context şi faptul că raportul tehnic [253] conţine proiectul cataloagelor
SGBD prototip MatBase; acestea au fost gândite ca o bd a cărei schemă este proiectată cu ajutorul
MMED (vezi prima parte a lucrării) ce fundamentează MatBase.
Cataloagele în DB2
DB2 al IBM, de exemplu, memorează şi statistici pentru optimizarea accesului în catalogul său
unic (din mai multe tabele, dar pentru toate bd gestionate). Datele statistice menţinute pentru fiecare
tabelă în parte includ:
• numărul de linii;
• numărul de pagini (fizice disc alocate tabelei);
• fişierele index definite pe coloanele tabelei;
• pentru fiecare index (arbori B+):
• adâncimea arborelui;
• numărul de pagini frunză;
• numărul de valori distincte ale cheii indexate;
60
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
• valorile maxime şi minime ale cheii, dar şi prima dintre valorile imediat sub, respectiv deasupra
acestora (pentru a evita derapaje statistice atunci când se calculează numărul probabil de linii
al tabelelor răspuns);
• distribuţia valorilor pentru primele 10 valori apărând cel mai des în cheie.
Meta-datele despre obiectele (tabele sau fişiere index) distribuite sunt replicate în catalogul
corespunzător din fiecare nod implicat. Pentru menţinerea integrităţii datelor, s-a optat pentru o uşoară
violare a autonomiei locale: crearea sau ştergerea unui obiect distribuit nu este admisă decât dacă toate
nodurile implicate sunt disponibile în acel moment (i.e. în stare de funcţionare şi accesibile în reţea).
Datele statistice sunt actualizate doar la cererea administratorilor de date; aceştia pot însă cere
NonStopSQL să facă automat actualizarea la intervale regulate de timp. Statisticile pot fi exacte (i.e.
luând în calcul toate datele implicate) sau aproximative (pentru care administratorul trebuie să precizeze
numărul de blocuri de 4K ce vor fi luate în considerare).
Cataloagele în Oracle
Oracle referă cataloagele drept dicţionare de date. Fiecare bd are propriul catalog, memorat
într-un segment de încărcare (“bootstrap segment”) întotdeauna alocat în spaţiul de tabelă SYSTEM.
Printre datele statistice suplimentare gestionate de Oracle se numără cele ce pot fi asociate fiecărei
instrucţiuni SQL; acestea includ timp total şi timp procesor de execuţie, număr de linii procesate,
numărul de accese logice şi fizice la disc etc.
Cataloagele în CA-OpenIngres
CA-OpenIngres al CA construieşte şi menţine câte un catalog (tot din mai multe tabele)
pentru fiecare bd în parte. În plus, fiind un SGBD distribuit, el menţine şi un catalog global, inclusiv cu
date statistice, care îi permite optimizarea interogărilor distribuite.
61
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
9. INTERFEŢE DE PROGRAMAREA
APLICAŢIILOR (API)
Orice SGBD oferă cel puţin o interfaţă de programare a aplicaţiilor (API), care să permită
programatorilor să facă uz de serviciile SGBD dintr-un limbaj de programare. Astfel, atunci când un
program scris într-un limbaj care beneficiază de un API are nevoie de acces la o bd gestionată de un
SGBD corespunzător, el nu are nevoie nici să cunoască detaliile de memorare a datelor (care poate sunt
memorate la distanţă, pe o platformă de un cu totul alt tip) şi nici să complice codul program cu foarte
multe instrucţiuni suplimentare (stabilirea şi controlul derulării comunicaţiilor la distanţă, navigarea între
tabele sau în tabele cu ajutorul indexurilor, sortare etc.).
Şi din acest punct de vedere, însă, situaţia este complet diferită pentru SGBD orientate obiect:
aşa cum am văzut (în capitolul 9) una din principalele caracteristici ale acestora este asigurarea doar a
unei extensii pentru manipularea obiectelor persistente de către un limbaj de programare orientat obiect
(sau cel mult două asemenea limbaje). Ca atare, deşi putem privi şi aceste extensii ca pe o API pentru
limbajul respectiv, nu aceasta este uzanţa într-un domeniu în care se urmăreşte mai degrabă integrarea
unui limbaj de programare existent în SGBD (acesta îndeplinind, ca atare, şi rolul de limbaj de definire şi
manipulare a datelor). Prin urmare, restul consideraţiilor dezvoltate în acest capitol exclud SGBDO.
Deşi sunt uzuale şi alte tipuri de limbaje de definire şi manipulare a datelor (precum QUEL,
bazat pe calculul predicativ al tuplilor, sau QBE, bazat pe calculul predicativ al coloanelor) majoritatea
SGBD oferă diverse variante de SQL (bazat pe algebra relaţională). Cum şi majoritatea implementărilor
de QBE traduc intern în SQL, iar QUEL este foarte puţin răspândit, ne vom focaliza atenţia în acest
capitol doar asupra SQL.
Dezavantajul acestei abordări este acela că sunt necesare precompilatoare care să traducă
SQL pentru compilatorul de limbaj gazdă în apeluri la serviciile SGBD corespunzătoare. Deoarece acest
pas suplimentar costă timp, SGBD mai noi oferă şi cel de-al doilea tip de API, care elimină necesitatea
preprocesării: biblioteci de programare cu primitive ce admit drept parametrii instrucţiuni SQL. Şi această
abordare, de tip apeluri SQL, are însă un mare dezavantaj, cel puţin deocamdată, deoarece, în absenţa
oricărei standardizări în domeniu, programele ce fac apel la asemenea biblioteci (care diferă foarte mult
între ele) nu sunt portabile.
62
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
Există însă şi multe aplicaţii de bd mereu previzibile şi care, în plus, trebuie reexecutate
frecvent (exemplu: calculul şi listarea vânzărilor, salariilor, stocurilor, comenzilor etc.). Pentru a le mări
viteza de execuţie, SGBD evoluate oferă şi SQL static, care memorează pe disc diversele variante
posibile de acces la ele şi modul de calcul al strategiei optime pentru asemenea tranzacţii. Singurul
dezavantaj major (dacă spaţiul disc suplimentar nu e o problemă) al acestei facilităţi este, evident, acela
că tranzacţiile trebuie “recompilate” manual ori de câte ori apar sau dispar noi indexuri.
O variantă intermediară între aceste două abordări, care elimină şi dezavantajul amintit imediat
mai sus, o constituie facilitatea procedurilor memorate pe care o pun la dispoziţie câteva SGBD.
Acestea nu memorează pe disc variantele de acces şi algoritmul de alegere a celei mai bune strategii
pentru o tranzacţie (precum SQL static), dar, pentru procedurile memorate pe disc (în fond nişte
subtranzacţii), păstrează în RAM aceste informaţii din momentul încărcării acestora în memorie şi până
la momentul scoaterii lor din RAM. În tot acest răstimp, orice altă tranzacţie care face apel la asemenea
proceduri (cu excepţia celei dintâi, evident), beneficiază de “precompilarea” optimizării accesului la
datele implicate.
Merită poate menţionat aici şi efortul firmei Borland, care încă de la versiunea Paradox 3.5, la
sfârşitul anilor 80, a pus la dispoziţie atât biblioteci de apeluri (chiar dacă primitive, nu de SQL) pentru C
şi Pascal (Paradox Engine), cât şi SQL Link, o interfaţă de acces la servere SQL. În ziua de azi, pe
piaţa SGBD doar pentru PC-uri, este frecventă posibilitatea cuplării cel puţin la Microsoft SQL Server
pentru Windows NT (server dezvoltat de Microsoft pornind de la licenţa SQL Server versiunea 4.2,
achiziţionată de la Sybase). În paralel, se oferă de către orice produs care se respectă (exemplu:
Access’95, ’97, Visual FoxPro, Paradox for Windows etc.) măcar acces la bibliotecile Windows API.
API în DB2
DB2 al IBM oferă API încorporat, cu SQL şi static şi dinamic, pentru foarte multe limbaje,
incluzând COBOL, C, FORTRAN, PL/1, Assembler, Ada, APL2, Prolog şi IBM Basic. Versiunea 4
suportă şi proceduri memorate.
API în Oracle
Oracle oferă doar SQL încorporat dinamic şi Oracle Call Interface (OCI), o API de tip apeluri,
pentru mai multe limbaje, incluzând C, COBOL, FORTRAN, Ada, PL/1 şi Pascal.
63
Facultatea de Matematică şi Informatică, Universitatea „Ovidius”
Curs SGBD I – III, 2007 - 2008
API în CA-OpenIngres
CA-OpenIngres, deşi construit în esenţă pe baza QUEL, suportă şi SQL, care poate fi
dinamic încorporat în destul de multe limbaje, incluzând Ada, COBOL, C, FORTRAN, Pascal,
PL/1 şi Basic. De asemenea, este suportată şi biblioteca Microsoft ODBC.
64