<titlu> i9g12gk
Notiuni fundamentale despre bazele de date si SQL</titlu>
<titlu>Scopuri</titlu>
• invatati care este modul de organizare a bazelor de date relationale
• invatati motivele pentru care bazele de date relationale constituie
medii mai bune de stocare a datelor decat fisierele
• invatati sa formati interogari SQL care obtin acces la datele
relationale si le manipuleaza
• invatati sa proiectati si sa creati baze de date relationale
Acest modul explica bazele de date relationale si modul de utilizare a acestora,
in comparatie cu fisierele, bazele de date relationale prezinta multe
avantaje, inclusiv o mai mare protectie a integritatii datelor si asigurarea
partajarii datelor. Acest modul se concentreaza asupra SQL, limbajul standard
pentru crearea, accesul si manipu¬larea bazelor de date relationale, in
cadrul modulului urmator, veti invata sa incor¬porati instructiuni
SQL in scripturile dumneavoastra PHP, astfel incat programele
dumneavoastra PHP sa poata lucra cu bazele de date relationale. Conceptele expli¬cate
in acest modul se aplica majoritatii bazelor de date relationale; cu toate
acestea, detaliile - cu precadere sintaxa SQL - sunt cele referitoare la MySQL,
cel mai popular limbaj de baze de date folosit cu PHP.
<titlu>Concepte ale bazelor de date relationale</titlu>
Nu cu mult timp in urma, bazele de date relationale constituiau o noutate.
Pe atunci, alte categorii de baze de date, precum cele de retea si ierarhice,
erau „la moda". Totusi, modelul bazelor de date relationale s-a dovedit
a fi mai eficient din punct de vedere al costurilor decat concurentii
sai. Aceasta sectiune explica modul de organizare a bazelor de date relationale
si ratiunile care justifica succesul mode¬lului bazelor de date relationale.
<titlu>Structura unei baze de date relationale</titlu>
O baza de date relationale stocheaza datele in tabele, care amintesc de
foile de calcul tabelar, iar fiecare tabel stocheaza informatii despre un anumit
tip de entitate. Practic, un tabel poate fi asimilat cu un fisier. De exemplu,
o baza de date relatio¬nala aferenta unei edituri poate include tabele precum
carte si autor.
Figura 13-1 prezinta un tabel caracteristic dintr-o baza de date relationala
care prezinta angajatii istorici ai Administratiei Statelor Unite ale Americii.
Primul rand al tabelului atribuie nume pentru fiecare coloana. Fiecare
rand al tabelului, altul decat primul rand, descrie un singur
angajat. De exemplu, al doilea rand descrie un angajat pe nume George
Washington*. Fiecare coloana, pe de alta parte, descrie un anumit atribut al
angajatului. De exemplu, a doua coloana contine numele angaja¬tilor, iar
a treia coloana contine anii in care s-au nascut acestia.
Pentru a se putea face referire la un anumit rand al tabelului, se obisnuieste
ca fiecare tabel sa contina o coloana care identifica in mod unic fiecare
rand. Aceasta coloana se numeste cheia primara a tabelului. In figura
13-1, coloana numita AngajatID serveste drept cheie primara. Daca nici o coloana
nu contine o valoare unica pentru fiecare rand, se pot combina valorile
mai multor coloane pentru a crea o cheie primara compusa.
<figura 13-1 Un tabel caracteristic dintr-o baza de date>
*AngajatID (Cheie primara)
*Nume
*AnNastere
*0001
*George Washington
*1732
*0002
*John Adams
*1735
*0003
*Thomas Jefferson
*1743
</figura 13-1>
O baza de date relationala se numeste astfel datorita capacitatii sale de a
stabili relatii intre date din mai multe tabele. Figura 13-2 prezinta
doua tabele si o relatie intre acestea. Noul tabel contine informatii
despre meseriile caracteristice ale angajatilor. Mai concret, tabelul il
identifica pe angajatul cel mai priceput intr-o anumita meserie. Numele
meseriei serveste drept cheie primara a tabelului, care mai contine, in
afara de aceasta, o singura coloana.
<figura 13-2 O relatie caracteristica intre doua tabele>
<Tabel angajati>
*AngajatID(Cheie primara)
*Nume
*AnNastere
*0001
*George Washington
*1732
*0002
*John Adams
*1735
*0003
*Thomas Jefferson
*1743
</Tabel angajati>
<Tabel meserii>
*Meserie (Cheie primara)
*AngajatID(Cheie externa)
*Arhitect
*0003
*General
*0001
*Filosof
*0002
</Tabel meserii>
</figura 13-2>
<nota>
*General american (1732-1799), primul presedinte al Statelor Unite ale Americii.
- N.T. </nota>
Coloana respectiva stocheaza atributul AngajatID al angajatului care cunoaste
meseria descrisa de un anumit rand. De exemplu, angajatul cu numarul 0003
este cel mai priceput arhitect. Retineti ca AngajatID este atat cheia
primara a tabelului original, dar si o coloana din noul tabel. Coloana AnagajatID
a noului tabel se numeste cheie externa; desi nu este cheia primara a noului
tabel, este cheia primara a unui alt tabel.
Aplicatia software care gazduieste o baza de date se numeste sistem de gestiune
a bazelor de date (SGBD). Exista multe sisteme de gestiune a bazelor de date
din surse deschise si comerciale. Printre cele mai populare asemenea sisteme
se numara:
<tabel>
*SGBD
*Tip
*DB2
*Comercial
*Interbase
*In trecut comercial; in prezent din sursa deschisa
*MySQL
*Sursa deschisa
* Oracle
*Comercial
* Postgresql
*Sursa deschisa
*SQL Server
*Comercial
* Sybase
*Comercial
</tabel>
MySQL este cel mai popular sistem de gestiune a bazelor de date destinat utilizarii
cu PHP, in mare masura deoarece este gratuit. Totusi, prin intermediul
PHP este posibil accesul la aproape orice SGBD modern. Pentru aceasta, nu aveti
nevoie decat de un program - cunoscut sub numele de driver- care se comporta
ca o interfata intre PHP si baza de date. Multe sisteme de gestiune a
bazelor de date sunt asociate cu programe driver care se conformeaza standardului
ODBC (Open Database Connectivity). Aceste sisteme de gestiune a bazelor de date
sunt accesibile prin intermediul caracteristicii ODBC a limbajului PHP.
<titlu>Ratiuni de utilizare a bazelor de date relationale</titlu>
In comparatie cu fisierele si bazele de date non-relationale, bazele de
date relationale prezinta un numar de avantaje si cateva dezavantaje.
Cunoscand atat avantajele, cat si dezavantajele, veti putea
determina cand este de preferat stocarea datelor intr-un fisier,
nu intr-o baza de date.
<titlu>Facilitarea partajarii datelor</titlu>
Avantajul definitoriu al unui SGBD relational il constituie capacitatea
de partajare a datelor. Acest fapt este important mai ales pentru aplicatiile
bazate pe Web, deoarece mai multi utilizatori pot obtine acces la aceleasi date
aproape simultan. Sistemele de gestiune a bazelor de date relationale includ
elemente de protectie, proiectate pentru a preveni pierderea actualizarilor
si deteriorarea datelor, care se pot produce in caz contrar in asemenea
circumstante. Mai mult, sistemele de gestiune a bazelor de date au o arhitectura
client-server care pune la dispozitia
utilizatorilor aflati la distanta, prin intermediul unei retele, date stocate
intr-o locatie centrala. Astfel, bazele de date relationale furnizeaza
partajarea datelor atat in timp, cat si in spatiu.
<titlu>Asigurarea independentei datelor</titlu>
Independenta datelor este un avantaj al bazelor de date care este depasit, ca
importanta, numai de partajarea datelor. Cand un program obtine accesul
la un fisier, datele sunt transferate programului in aceeasi maniera in
care sunt stocate. Prin contrast, programatorii folosesc un limbaj special pentru
a solicita date dintr-o baza de date relationala. Programatorii pot solicita
ca datele respective sa fie transferate in orice forma o doresc acestia,
indiferent de modul de stocare a datelor, in particular, programatorii
pot solicita numai coloanele unui tabel necesare intr-o anumita aplicatie.
Aceasta caracteristica este importanta atunci cand la o baza de date sunt
adaugate coloane noi. Datorita independentei datelor, programele existente anterior
continua sa functioneze si dupa modificarea bazei de date. Prin contrast, adaugarea
unui camp la un fisier impune, in general, revizuirea fiecarui program
care obtine acces la fisier.
<titlu>Interogarea ad-hoc</titlu>
Bazele de date relationale inteleg SQL (Structured Query Language*), un
limbaj relativ simplu, folosit pentru solicitarea datelor. Totusi, in
ciuda simplitatii sale, SQL este un limbaj foarte puternic, care poate obtine
accesul la date stocate in mai multe tabele, poate filtra datele dorite
si poate sorta, rezuma si afisa rezultatele.
In general, nu se pot anticipa toate modalitatile in care utilizatorii
pot dori sa obtina acces la date si sa le vizualizeze. Ca atare, nu se pot scrie
programe de aplicatie care sa satisfaca fiecare potentiala necesitate de informatii.
Este aproape sigur ca vor aparea unele cereri de date neprevazute (sau ad hoc).
Utilizand SQL, este posibil accesul la datele stocate intr-o baza
de date relationala fara a scrie un program de aplicatie, permitand frecvent
evitarea intarzierilor si a costurilor implicate de programarea
personalizata. Astfel, bazele de date relatio¬nale permit satisfacerea tuturor
cererilor ad-hoc de informatii, care ar ramane fara raspuns in alte
situatii.
<titlu>Organizarea datelor</titlu>
In general, bazele de date relationale isi stocheaza datele intr-un
singur fisier sau catalog. Aceasta caracteristica de organizare faciliteaza
administrarea datelor, deoa¬rece executarea copiei de siguranta, respectiv
restaurarea unui singur fisier sau
<nota>
In traducere limbaj de interogare structurat - N.T. </nota>
catalog sunt mai simpla decat operatiile similare aplicate unui set de
fisiere stocat in mai multe cataloage.
<titlu>Asigurarea datelor</titlu>
In general, bazele de date relationale protejeaza datele impotriva
accesului neautorizat. De exemplu, fisierele care stocheaza tabelele relationale
pot fi accesibile numai pentru administratorul de sistem si pentru un cont special
de utilizator, creat pentru gestionarea bazei de date.
<titlu>Reducerea la minimum a experientei necesare in domeniul
programarii</titlu>
In general, sistemele moderne de gestiune a bazelor de date folosesc complexitatea
pentru a da iluzia simplitatii. Datorita, complexitatii acestora, in general
este mai simplu sa se scrie un program care foloseste o baza de date relationala
decat sa i se scrie un program echivalent din punct de vedere functional,
dar care foloseste fisiere obisnuite. Mai mult, o aplicatie scrisa folosind
un SGBD va prezenta mai putine defecte decat o aplicatie echivalenta din
punct de vedere functional, scrisa folosind fisiere normale.
In general, autorii sistemelor de gestiune a bazelor de date beneficiaza
de o bogata experienta, pe care si-au utilizat-o prin crearea de programe reutilizabile
la care alti programatori obtin acces prin intermediul functiilor definite cu
interfete simple. Asa cum un sistem de operare scuteste programatorii de necesitatea
de a intelege mecanismele detaliate de functionare ale dispozitivelor
hardware, o baza de date relationala ii scuteste pe programatori de necesitatea
de a intelege o varietate de probleme complexe care pot aparea la partajarea
datelor.
<titlu>Obtinerea eficientei in prelucrarea datelor</titlu>
Datorita complexitatii lor, sistemele de gestiune a bazelor de date relationale,
necesita mai multe cicluri de procesor pentru a satisface o cerere de date decat
cele necesare pentru accesul la un fisier ordinar. In acest sens, sistemele
de gestiune a bazelor de date relationale sunt ineficiente. Totusi, daca examinam
chestiunea dintr-o alta perspectiva, putem ajunge la o concluzie diferita.
De exemplu, doriti sa calculati dimensiunea medie a gospodariilor americane
folosind datele biroului de recensamant. Daca aceste date ar fi fost stocate
intr-un fisier obisnuit, ati scrie un program care sa includa un ciclu
care citeste fiecare inregistrare a fisierului si incrementeaza contoare
pentru dimensiune si numarul de gospodarii. Sa presupunem ca fisierul de recensamant
este stocat pe un calculator aflat la distanta, la care obtineti acces prin
intermediul unei retele, in acest caz,
fiecare inregistrare de recensamant este trimisa prin retea, creand
un adevarat blocaj de trafic. Totusi, daca datele de recensamant ar fi
fost stocate intr-o baza de date relationala, puteti pur si simplu folosi
SQL pentru a solicita calculul dimensiunii medii a unei gospodarii. Astfel,
singurele date trimise prin retea ar fi rezultatul insusi. Deci, utilizarea
unui SGBD relational nu este intotdeauna mai putin eficienta decat
folosirea unor fisiere normale.
<titlu>Decizia de utilizare a unui SGBD relational</titlu>
Din punctul de vedere al unei firme, utilizarea unei tehnologii este adecvata
atunci cand avantajele utilizarii depasesc costurile, in cazul unui
SGBD relational, principalul cost incremental in comparatie cu fisierele
obisnuite consta in necesi¬tatea unor resurse mai mari de prelucrare
a datelor. Aceasta presupune, desigur, ca alegeti un SGBD din sursa deschisa,
care este disponibil gratuit; in caz contrar, vor aparea costuri pentru
achizitionarea si intretinerea sistemului comercial de gestiune a bazelor
de date ales de dumneavoastra.
Asa cum s-a explicat in sub-sectiunile precedente, avantajele incrementale
ale unui SGBD relational sunt numeroase. Acolo unde acestea sunt importante,
avan¬tajele unui SGBD depasesc, in general, costurile. Fisierele normale
raman adecvate pentru date relativ statice, care nu sunt partajate, nu
sunt supuse la interogari ad-hoc, nu sunt confidentiale sau extrem de valoroase
si sunt folosite de un numar redus de programe. Cu alte cuvinte, implementarea
unor aplicatii foarte simple poate fi mai eficienta sub aspectul costurilor
daca se folosesc fisiere normale si nu SGBD; cu toate acestea, majoritatea aplicatiilor
importante sunt mai eficiente din punct de vedere al costurilor daca sunt implementate
folosind un SGBD.
<Sfatul specialistului>
Intrebare: Care este sistemul de gestiune a bazelor de date pe care trebuie
sa-l folosesc pentru aplicatia mea?,
Raspuns: Asa cum s-a mentionat anterior, MySQL este cel mai important SGBD destinat
utilizarii cu PHP. Totusi, Postgresql este de asemenea un SGBD din sursa deschisa
si este disponibil gratuit, in comparatie cu MySQL, Postgresql furnizeaza
functii suplimentare, care faciliteaza scrierea programelor ce asigura integritatea
tranzactiilor. Trebuie sa folositi Postgresql daca baza dumneavoastra de date
va fi actualizata frecvent si cu volume mari de date. Daca baza dumneavoastra
de date este asociata unui sistem comercial, trebuie sa aveti la dispozitie
fonduri pentru achizitionarea unui SGBD comercial. Un SGBD comercial trebuie
selectionat in functie de numerosi factori, inclusiv experienta dumneavoastra
cu producatorul respectiv si dimensiunea bugetului de care dispuneti. </Sfatul
specialistului>
<Test „la minut">
• Care este componenta unei baze de date relationale care stocheaza informatii
despre o anumita categorie de entitate?
• Care este componenta unei baze de date relationale care stocheaza informatii
despre un anumit exemplu de entitate?
• Care este componenta unei baze de date relationale care stocheaza valorile
unei anumite caracteristici pentru un set de entitati?
</Test „la minut">
<titlu>Implementarea unei baze de date</titlu>
Implementarea unei baze de date relationale este un subiect de o amploare considerabila
si a fost abordata in cadrul a numeroase carti. Aceasta sectiune ofera
o trecere in revista a implementarii bazelor de date relationale, care
descrie procesele de proiectare si creare a unei baze de date pornind de la
o perspectiva simpla, practica. Scopul sectiunii de fata consta in a va
oferi cunostintele necesare pentru a implementa baze de date MySQL simple, accesibile
programelor PHP.
<titlu>Proiectarea unei baze de date,/titlu>
Un instrument frecvent utilizat de proiectare a bazelor de date consta din procedeul
cunoscut sub numele de modelare entitate-relatie sau modelare E-R. In
contextul modelarii E-R, o entitate este similara cu un tabel relational; cu
alte cuvinte, contine date care descriu un set de individualitati corelate.
Modelarea E-R este un proces in cadrul caruia coloanele, entitatile si
relatiile intre entitati sunt descoperite si organi¬zate. Un model
E-R poate fi rafinat cu usurinta, pentru a genera o structura a unei baze de
date, care poate fi transformata intr-o baza de date relationala efectiva.
<titlu>Modelare E-R </titlu>
Procesul de modelare E-R consta din patru faze principale:
1. Identificarea coloanelor
2. Gruparea coloanelor in entitati
3. Identificarea cheilor primare
4. Identificarea cheilor externe
<nota>
Raspunsuri la test
• Tabel
• Rand
• Coloana</nota>
<titlu>Identificarea coloanelor</titlu>
Prima operatie din cadrul procesului de modelare E-R este identificarea coloanelor.
Deseori, aceasta operatie este executata de un grup de persoane, care actio¬neaza
sub indrumarea si sfatul unei persoane cu experienta in domeniu.
Sa ne reamintim ca o coloana inregistreaza o singura caracteristica a
unei entitati, in esenta, grupul identifica posibile coloane punand
intrebarea: „Care sunt datele sau caracteristicile pe care trebuie
sa le stocheze sistemul?". Coloanele candidate sunt puse pe lista de indata
ce sunt identificate, in acest scop se foloseste frecvent o tabla, deci
participantii pot vedea lista pe masura ce aceasta incepe sa se con¬tureze
si pot modifica lista rapid, conform necesitatilor.
In incercarea de identificare a coloanelor, in general este
util sa se raspunda la unele intrebari conexe, cum sunt urmatoarele:
• Care sunt deciziile pe care sistemul trebuie sa le ia sau sa le sustina?
• Care sunt operatiile pe care sistemul trebuie sa le execute sau sa le
sustina?
• Care sunt datele necesare pentru a lua aceste decizii si pentru a efectua
aceste operatii?
In momentul in care nu mai pot fi gasite si alte coloane candidate,
procesul trece la faza urmatoare, si anume gruparea coloanelor in entitati.
<titlu>Gruparea coloanelor in entitati</titlu>
De obicei, este evident ca unele coloane sunt corelate, in sensul ca fac
referire la un anumit set de individualitati corelate. De exemplu, coloane precum
autor, titlu si pret de coperta se pot corela cu notiunea de carti. Ca atare,
aceste coloane pot fi grupate pentru a forma o entitate, cum este carte. Uneori,
o coloana data este corelata cu mai multe entitati; in acest caz, coloana
poate aparea de mai multe ori pe lista.
O data entitatile identificate, este util sa acordam o oarecare atentie numelor.
Limbajul SQL folosit cu bazele de date relationale impune unele restrictii asupra
numelor. Este utila revizuirea numelor care nu se conformeaza acestor restrictii,
pentru a evita problemele ce pot aparea in etapele viitoare ale procesului
de proiec¬tare. Cel mai bine este ca numele coloanelor si ale entitatilor
sa respecte urma¬toarele restrictii:
• Trebuie sa inceapa cu o litera
• Trebuie sa contina numai litere, cifre si caracterul de subliniere (
_ ).
• Lungimea lor nu trebuie sa depaseasca 64 de caractere
• Trebuie sa fie tratate ca insensibile la diferenta intre majuscule
si minuscule (de exemplu, nu trebuie sa aveti coloane distincte cu numele abc
si ABC)
Dupa ce ati grupat coloanele in entitati, puteti trece la identificarea
cheii primare pentru fiecare entitate.
<remarca>
Majoritatea sistemelor de gestiune a bazelor de date, inclusiv MySQL, impun
restrictii mai putin severe decat cele recomandate. Dar, prin respectarea
restrictiilor recomandate, puteti evita o multime de probleme cu SGBD, HTML
si PHP. </remarca>
<titlu>Identificarea cheilor primare</titlu>
In cele din urma, fiecare entitate va deveni un tabel relational si, ca
atare, va trebui sa aiba o cheie primara. Examinati fiecare entitate pentru
a determina daca una dintre coloanele sale asociate are o valoare unica pentru
fiecare dintre aparitiile entitatii. Daca o asemenea coloana exista, o veti
identifica drept cheie primara a entitatii. De exemplu, puteti identifica valoarea
CodNumericPersonal ca fiind cheia primara a unei entitati care contine informatii
referitoare la contribuabili pentru anul in curs.
Puteti gasi unele entitati care nu contin nici o coloana adecvata pentru rolul
de cheie primara, intr-o asemenea situatie, puteti cauta o serie de coloane
care au o valoare combinata unica. Daca descoperiti o asemenea serie, o puteti
identifica drept cheie primara compusa a entitatii. De exemplu CodNumericPersonal
si AnFiscal pot servi impreuna drept cheie primara a unei entitati care
contine informatii referitoare la contribuabili pentru mai multi ani.
S-ar putea sa nu descoperiti nici o coloana sau serie de coloane care sa identifice
in mod unic fiecare aparitie a unei entitati, in acest caz, creati
o coloana noua, care va contine o identificare artificiala unica, si identificati
noua coloana ca fiind cheia primara a entitatii. De exemplu, in cazul
unei entitati numite angajat, puteti denumi identificarea artificiala angajatid
sau angajatnr, ultimul nume fiind o abreviere frecvent folosita pentru o coloana
care altfel s-ar fi numit angajat_numar.
<Sugestie>
Puteti dori sa folositi o identificare artificiala unica chiar si atunci cand
una sau mai multe coloane pot servi drept cheie primara. Astfel, evitati problemele
care apar cand identificatori presupusi unici se dovedesc a nu fi unici.
De exemplu, se presupune ca valoarea codului numeric personal este unica; dar
un angajat poate introduce informatii incorecte, determinand un conflict
intre identificatorul propriu presupus unic si identifi¬catorul unui
alt angajat. </Sugestie>
<titlu>Identificarea cheilor externe</titlu>
Operatia finala si cea mai dificila din cadrul activitatii de modelare E-R o
constitue identificarea cheilor externe. Sa ne reamintim ca acestea sunt pur
si simplu coloane caror valori sunt corelate cu acelea ale valorilor cheilor
primare ale unei entitati oarecare. Procesul de identificare a cheilor externe
consta in compararea coloanelor cu cheile primare si, pentru fiecare combinatie
posibila, in raspunsul la intrebarea: „Exista o relatie intre
valoarea acestei coloane si valoarea acestei chei primare?"
Majoritatea celor care practica modelarea E-R folosesc un fel de diagrama,
cunoscuta sub numele de diagrama E-R, pentru a le fi de ajutor la documentarea
cheilor externe. Figura 13-3 prezinta o diagrama E-R caracteristica, diagrama
care descrie tabelele relationale prezentate anterior in figura 13-2.
O diagrama E-R reprezinta entitatile sub forma de dreptunghiuri, iar relatiile
dintre entitati sub forma de romburi. O relatie exista oriunde a fost identificata
o cheie externa. Relatia stie meseria din figura 13-3 s-a stabilit intre
entitatile numite angajat si meserii. Uneori, diagramele E-R prezinta campurile
asociate fiecarei entitati; deoarece astfel se obtin deseori diagrame aglomerate,
acest procedeu nu este frecvent folosit. Cu toate acestea, il puteti gasi
util, mai ales pentru modelele E-R mici.
Stricto sensu, aceasta activitate de modelare E-R implica mai mult decat
o simpla identificare a cheilor externe. O data identificata o relatie, aceasta
trebuie clasificata si eventual revizuita. Pentru a clasifica relatia, ganditi-va
la numarul de aparitii ale entitatii implicate in relatie, care poate
fi zero, unu sau mai multe, in relatia stie meseria, fiecare angajat are
exact o meserie. O asemenea relatie se numeste relatie de tip 1:1. Totusi, sunt
posibile si alte cardinalitati ale relatiilor, asa cum se numesc acestea.
De exemplu, o carte poate avea mai multi autori. Astfel, relatia dintre entitatile
numite carte si autor este o relatie de tip unu la mai multi si se abreviaza
frecvent sub forma 1:N. Unele relatii sunt optionale; de exemplu, un angajat
poate fi casa¬torit sau nu. Relatia dintre angajat si sot/sotie este o relatie
de tip 1:0. Cu alte cuvinte, un angajat poate fi casatorit sau nu; dar un angajat
casatorit are exact un sot, respectiv o sotie.
<figura 13-3 O diagrama E-R caracteristica> angajat - stie meseria - meserii
</figura 13-3>
Si mai interesante sunt lectiile de tip N:N. Un exemplu de asemenea relatie
este cea intre curs si student. Relatia este de tip N:N deoarece la fiecare
curs pot fi inscrisi mai multi studenti, iar fiecare student poate fi
inscris la mai multe cursuri. O asemenea lectie este nedefinita si indica
lipsa unei entitati, in acest caz, entitatea inscriere. Ori de cate
ori descoperiti o entitate N:N, trebuie sa determinati si sa adaugati entitatea
care lipseste. Dupa ce ati adaugat entitatea lipsa, trebuie sa modi¬ficati
lectiile.
Deseori, entitatea lipsa este corecta cu una sau mai multe coloane care lipsesc.
De exemplu, in cazul entitatii lipsa inscriere, coloana nota va
lipsi, deoarece nu poate fi plasata in mod justificat nici in tabelul
curs, nici in tabelul student. Coloana
nota se refera la o relatie intre un curs si un student, nu numai la
un curs sau la un student.
Dupa adaugarea entitatilor care lipsesc, toate relatiile de tip N:N trebuie
sa dispara. De exemplu, relatia intre curs si inscriere este de
tip 1:N, deoarece pot exista mai multe inscrieri la un curs dat, dar fiecare
inscriere se refera la un anumit curs. Similar, relatia dintre inscriere
si student este N: l, deoarece fiecare inscriere se refera la un anumit
student, care se poate inscrie la mai multe cursuri.
Dupa ce ati eliminat relatiile de tip N:N, puteti lua in considerare normalizarea
bazei de date descrise de modelul E-R.
<titlu>Normalizarea unei baze de date</titlu>
O baza de date normalizata este una care a fost transformata astfel incat
sa satisfaca o serie de reguli. Regulile de normalizare a bazelor de date sunt
descrise ca proprietati pe care o baza de date care respecta aceste reguli trebuie
sa le aiba, proprietati cunoscute sub numele de forme. Setul cel mai frecvent
aplicat de reguli de normalizare a bazelor de date include trei reguli, care
descriu prima, a doua si a treia forma normala.
Aceste forme sunt destinate a preveni problemele care pot aparea in cadrul
bazelor de date care nu le respecta. Totusi, aceste reguli sunt derutante si
dificil inteles pentru multi. Sub-sectiunea de fata prezinta pe scurt
o abordare de bun simt a normalizarii bazelor de date, adecvata pentru evitarea
a numeroase probleme frecvent intalnite legate de proiectarea bazelor
de date. Proiectantii bazelor de date foarte simple pot opta in mod logic
pentru omiterea in totalitate a normalizarii bazelor de date, intrucat
problemele de proiectare pot fi corectate pur si simplu aparitia lor, in
cursul programarii sau al utilizarii. Totusi, normalizarea bazelor de date este
esentiala pentru bazele de date mari, unde costul si efortul de descoperire
si remediere a unei erori poate depasi semnificativ costul si efortul implicate
in normalizarea bazelor de date.
<titlu.Regula 1: Este permisa numai utilizarea valorilor atomice</titlu.
Un tabel dintr-o baza de date trebuie sa contina numai valori atomice. Cu alte
cuvinte, nici o coloana nu trebuie sa contina valori compuse. De asemenea, nici|
o coloana nu trebuie sa reprezinte un grup repetitiv.
Aceasta regula se aplica pentru coloane precum nume, alcatuita din prenume,
initiala mijlocie si numele de familie. O asemenea coloana are o valoare compusa
trebuie divizata in trei coloane separate: prenume, initiala_mijlocie
si nume_familie. Aceasta regula este frecvent incalcata, deseori la un
pret redus. Dezavantajul incalcarii acestei reguli este ingreunarea
in SQL a accesului la componentele unei co¬loane compuse.
Interdictia indreptata impotriva grupurilor care se repeta este
o problema mai serioasa. Sa luam in considerare un tabel care include
un grup repetitiv de adrese de e-mail. Care este numarul de repetitii permis?
Doua, trei, cinci, zece? Pentru a evita limitarea artificiala a numarului de
repetitii, structura bazei de date trebuie sa fie revizuita, pentru a plasa
grupul repetitiv intr-un alt tabel. De exemplu, structura urmatoare:
contact table: contactid (cheie primara) nume email1 email2 email3
trebuie inlocuita cu o structura ca urmatoarea:
contact table: contactid (cheie primara) nume
email table: emailid (cheie primara) contactid (cheie externa) email
<Sugestie>
Pentru a evita incalcarea acestei reguli, eliminati toate grupurile repetitive
prin definirea unuia sau mai multor tabele care sa contina grupurile respective.
</Sugestie>
<titlu>Regula 2: Bazati-va pe cheia primara in totalitatea sa</titlu>
Coloanele dintr-un tabel trebuie sa se bazeze pe cheia primara in totalitatea
sa. Pentru a vedea care este modul de functionare al acestei reguli, luati in
considerare urmatorul tabel, care incalca regula:
inscriere table: studentid cursid studentnume
Sa presupunem ca studentid si cursid au fost desemnate drept cheie primara
compusa. Coloana studentnume este asociata unui student, nu unei inscrieri.
In consecinta, depinde de valoarea studentid, dar nu si de valoarea cursid.
Daca un student s-a inscris la mai multe cursuri, atunci studentului respectiv
ii vor fi asociate mai multe randuri inscriere, fiecare cu
o coloana studentnume. Daca se descopera ca numele studentului a fost gresit
ortografiat, trebuie corectate mai multe randuri din tabel; in caz
contrar, unele randuri vor avea valori incorecte in anumite coloane.
Se vor evita bazele de date inconsecvente, deci structurile in care o
coloana depinde numai de o portiune a cheii primare sunt interzise prin aceasta
regula.
<sugestie>
Aceasta regula se aplica numai tabelelor cu o cheie primara compusa. O metoda
buna de a evita incalcarea acestei reguli este a folosi o cheie primara
artificiala si nu o cheie primara compusa, convenabila in alte conditii.</sugestie>
<titlu>Regula 3: Bazati-va numai pe cheia primara</titlu>
Coloanele dintr-un tabel trebuie sa se bazeze numai pe cheia primara. Iata un
exemplu de tabel care incalca regula:
curs table: cursid (cheie primara) cursnume deptid deptnume
Acest tabel inregistreaza identificatorul cursului, numele cursului,
identificatorul departamentului si numele departamentului pentru cursuri. Cu
toate acestea, coloana deptnume nu depinde de cursid; in schimb, depinde
de deptid. Cu alte cuvinte tabelul descrie atat cursurile, cat si
departamentele, in consecinta, numele departa¬mentului apare in
mod redundant in fiecare rand care se refera la un curs asociat
departamentului. Structura trebuie revizuita dupa cum urmeaza:
curs table: cursid (cheie primara) cursnume deptid (cheie externa)
departament table: depid (cheie primara) deptnume
<Sugestie>
Pentru a evita incalcarea acestei reguli, cautati tabele care contin informatii
despre mai multe categorii de entitati. Toate aceste tabele trebuie divizate
in tabele separate, unite printr-o cheie externa. </Sugestie>
<titlu>Rafinarea modelelor E-R</titlu>
Ultima operatie de finete aplicata unui model E-R consta in specificarea
unui tip de date pentru fiecare coloana. Majoritatea bazelor de date relationale
accepta urmatoarele tipuri de date generale:
• Caracter
• Intreg
• Zecimal
• Data si ora
• Binar
Tabelul 13-1 rezuma numeroase tipuri de date frecvent utilizate, acceptate
de MySQL si de majoritatea celorlaltor sisteme de baze de date relationale.
Totusi, MySQL accepta multe alte tipuri de date. Consultati manualul de referinta
MySQL pentru mai multe informatii cu privire la aceste tipuri si la altele.
<tabel 13-1 Principalele tipuri de date din MySQL>
* Tip de date
*Descriere
* BLOB
*Date binare arbitrare, cu o lungime maxima de 65535 octeti.
* CHAR(m)
*Un sir de caractere de lungime fixa, cu un maxim de m caractere, unde m este
mai mic decat 256. Pentru obtinerea lungimii dorite, se insereaza spatii
finale.
*DATE
*O data in format an-luna-zi; de exemplu 2005-12-31.
* DECIMAL
DECIMAL(m,d)
*Un numar zecimal, reprezentat sub forma de sir cu m cifre, din care d se afla
la dreapta punctului zecimal. Daca m si d sunt omise, in mod prestabilit
se vor utiliza valorile 10 si 0.
*DOUBLE
DOUBLE (m, d)
*Un numar cu virgula mobila, cu dubla precizie, avand o latime de afisare
egala cu m si un numar de d cifre dupa virgula.
* FLOAT(m,d)
*Un numar cu virgula mobila, cu simpla precizie, avand o latime de afisare
egala cu m si un numar de d cifre dupa virgula.
* INTEGER
INTEGER UNSIGNED
*Un intreg pe 32 de biti. Daca se specifica atributul UNSIGNED, domeniul
de valori este cuprins intre 0 si 4294967295; in caz contrar, domeniul
este cuprins intre valorile -2147483648 si 2147483647.
* NUMERIC
NUMERIC (m, d)
*Similar cu DECIMAL.
*REAL
REAL(m, d)
* Similar cu DOUBLE.
*SMALLINT
SMALLINT UNSIGNED
* Un intreg pe 16 biti. Daca se specifica atributul UNSIGNED, domeniul
de valori este cuprins intre 0 si 65535; in caz contrar, domeniul
este cuprins intre valorile -;32768 si 32767.
*TIME
TIMESTAMP
TIMESTAMP(m)
*Ora in format ora-minut-secunda; de exemplu, 08-30-00. O valoare de tip
data si ora, in format an-luna-zi ora-minut-secunda; de exemplu, 1970-01-01
00:00:00. Aceasta reprezentare este similara celei returnate de functiile UNIX
si nu poate codifica date situate dincolo de un anumit moment al anului 2037.
*VARCHAR(m)
*Un sir caracter de lungime variabila, cu un maximum de m carac¬tere, unde
m este mai mic decat 256. Spatiile finale au fost eliminate.
</tabel 13-1>
Iata unele reguli empirice pentru selectarea tipurilor de date:
• Alegeti BLOB ca tip pentru datele pe care nu trebuie sa le manipulati
si la care nu veti obtine acces prin intermediul limbajului SQL.
• Alegeti un tip data sau ora adecvat pentru coloanele care contin date
calendaristice sau ore.
• Alegeti un tip numeric pentru coloanele folosite in calcule.
- Pentru cantitati foarte mari sau foarte mici, alegeti DOUBLE ca tip de date.
- Pentru coloane care contin numere fara parte zecimala de dimensiuni adecvate,
alegeti SMALLINT sau INTEGER ca tip de date.
- Pentru alte coloane care contin date numerice, alegeti DECIMAL ca tip de date.
• Alegeti CHAR sau VARCHAR ca tip pentru celelalte coloane, chiar si pentru
cele care contin mai ales cifre, cum ar fi un cod postal.
<sugestie>
Cand alegeti un tip de date, nu uitati sa alocati spatiu pentru eventuale
cresteri. De exemplu, nu specificati un numar de client format din doua cifre
decat daca sunteti sigur ca nu veti avea niciodata mai mult de 100 de
clienti.</sugestie>
<titlu>Crearea unei baze de date MySQL</titlu>
Administratorul de sistem creeaza baze de date MySQL. La inceput, o baza
de date nu contine tabele. Pentru a crea un tabel intr-o baza de date,
folositi un sub-limbaj SQL special, cunoscut sub numele de Data Definition Language*
(DDL). Aceasta sub-sectiune este dedicata formelor pe care le pot lua comenzile
DDL. Puteti emite comenzi DDL si alte comenzi SQL prin intermediul unui interpretor
SQL sau prin intermediul PHP. Proiectele din acest modul prezinta modul de emitere
a comenzilor SQL folosind un interpretor SQL. Modulul urmator prezinta modul
de emitere a comenzilor SQL utilizand PHP.
Pentru a crea un tabel intr-o baza de date, emiteti comanda CREATE TABLE,
care are urmatoarea forma:
CREATE TABLE tabel (coloana tip, coloana tip, …);
unde tabel este numele tabelului, coloana este numele unei coloane, tip este
tipul datelor incluse in coloana, iar ... arata ca se poate specifica
un numar nedefinit de coloane si tipuri. De exemplu, comanda urmatoare creeaza
un tabel numit carte, care contine coloanele ISBN (un identificator unic asociat
unei carti), titlu si pret:
CREATE TABLE carte (carteid CHAR(10), titlu VARCHAR(255), pret decimal(5,2));**
In general, SQL nu este sensibil la diferenta intre majuscule si
minuscule. Deci, daca preferati, puteti emite comanda urmatoare, care se comporta
exact la fel ca si precedenta:
create table carte (carteid char(10), titlu varchar(255), pret decimal(5,2));
<nota>
*In traducere limbaj de definitie a datelor - NT
**S-a preferat acest tip de date deoarece preturile in Statele Unite,
sunt exprimate in dolari si centi. Pentru a exprima un pret de carte in
Romania, se poate folosi definitia INTEGER UNSINGNED, deoarece nu se mai
foloseste banul ca subdiviziune a leului -NT</nota>
<sugestie>
Programele dumneavoastra SQL vor fi mai usor de citit daca respectati un anumit
stil. De exemplu, puteti scrie toate cuvintele cheie SQL cu majuscule, iar cuvintele
furnizate de programator-cu minuscule.</sugestie>
In afara tipului de date, puteti specifica numeroase atribute optionale
ale unei coloane:
<tabel>
*Atribut
*Descriere
*NOT NULL
*Fiecare rand trebuie sa contina o valoare a coloanei asociate; valorile nule nu sunt permise.
*DEFAULT valoare
*Daca nu este data o valoare a coloanei asociate, se va presupune valoarea specificata.
*AUTO- INCREMENT
*MySQL va repartiza in mod automat un numar de serie ca valoare a coloanei
asociate.
*PRIMARY KEY
*Coloana asociata este cheia primara a tabelului care o contine.
</tabel>
Iata o comanda CREATE TABLE ceva mai complicata, care foloseste unele atribute
optionale:
CREATE TABLE carte (carteid CHAR(10) PRIMARY KEY, titlu VARCHAR(255) NOT NULL, pret DECIMAL(5,2) DEFAULT 50.00);
<titlu>Stergerea unui tabel</titlu>
Stergerea unui tabel este o operatie simpla. Prin stergerea unui tabel, sunt
eliminate toate randurile incluse in tabel. Pentru a sterge un tabel,
emiteti urmatoarea comanda:
DROP TABLE tabel;
unde tabel este numele tabelului care urmeaza a fi sters.
<Atentie>
Stergerea unui tabel este un act irevocabil; asigurati-va ca intentionati sa
stergeti tabelul inainte de a emite o comanda DROP TABLE; de asemenea,
asigurati-va ca ati scris corect comanda inainte de a apasa pe tasta ENTER.
</Atentie>
<titlu>Modificarea unui tabel</titlu>
Dupa crearea unui tabel, il puteti modifica prin emiterea unei comenzi
ALTER TABLE. O forma a comenzii va permite sa stergeti o coloana din tabel:
ALTER TABLE tabel DROP coloana;
unde tabel este numele tabelului care va fi modificat, iar coloana este numele
coloanei care va fi stearsa. De exemplu, pentru a sterge coloana pret din tabelul
carte, emiteti comanda
ALTER TABLE carte DROP pret;
<Atentie >
Stergerea unei coloane este un act irevocabil; asigurati-va ca intentionati
sa stergeti coloana inainte de a emite o comanda ALTER TABLE; de asemenea,
asigurati-va ca ati scris corect comanda inainte de a apasa pe tasta ENTER.
</Atentie >
O alta forma a comenzii va permite sa adaugati o noua coloana in tabel:
ALTER TABLE tabel ADD coloana tip aoptiunii;
unde tabel este numele tabelului care va fi modificat, coloana este numele
coloanei care va fi adaugata, tip este tipul noii coloane, iar aoptiunii constituie
toate optiu¬nile dorite, precum PRIMARY KEY. De exemplu, pentru a adauga
din nou coloana pret la tabelul carte, emiteti comanda:
ALTER TABLE carte ADD pret DECIMAL(5,2) DEFAULT 50.00;
<titlu>Acordarea si revocarea privilegiilor de acces</titlu>
Cand un utilizator incearca sa obtina acces la o baza de date relationala,
SGBD verifica daca utilizatorul are permisiunea de a executa operatia. Administratorul
de sistem poate folosi comanda MySQL GRANT pentru a autoriza un utilizator sa
obtina accesul la un tabel din baza de date. Comanda are urmatoarea forma:
GRANT ALL ON tabel TO utilizator IDENTIFIED BY ’parola’;
unde tabel este numele tabelului, utilizator este numele contului de utilizator,
iar parola este parola pe care o va furniza utilizatorul pentru a-si proba identitatea.
Alternativ, administratorul de sistem poate autoriza un utilizator sa obtina
acces la orice tabel dintr-o baza de date specificata, folosind urmatoarea forma
a comenzii GRANT:
GRANT ALL ON baza_de_date.* TO utilizator IDENTIFIED BY ’parola’;
De exemplu, comanda urmatoare autorizeaza pe utilizatorul php sa obtina acces
la toate tabelele din baza de date numita testdb, ori de cate ori utilizatorul
furnizeaza parola specificata:
GRANT ALL ON testdb.* TO php IDENTIFIED BY ’eusuntala’;
Comanda. REVOKE se poate folosi pentru retragerea privilegiilor acordate anterior.
Comanda are urmatoarele forme:
REVOKE ALL ON tabel FROM utilizator;
REVOKE ALL ON baza_de_date.* FROM utilizator;
De exemplu, pentru a revoca toate privilegiile utilizatorului baiat_rau, emiteti
comanda:
REVOKE ALL ON *.* FROM baiat_rau;
<Sfatul specialistului>
Intrebare: Asa cum s-a aratat anterior, accesul la un tabel relational
pare a fi ceva de genul „totul sau nimic". Nu exista nici o modalitate
de a se acorda acces numai la anumite coloane?
Raspuns: Da, administratorul de sistem poate folosi o forma mai complexa comenzii
GRANT pentru a autoriza accesul numai la coloanele specificate. Forma corespunzatoare
a comenzii este:
GRANT privilegiu (coloane) ON tabel TO utilizator IDENTIFIED BY 'parola’; sau
GRANT privilegiu (coloane) ON baza_de_date.* TO utilizator IDENTIFIED BY 'parola’; unde privilegiu este privilegiul care urmeaza a fi extins, coloane sunt coloanele
carora li se aplica privilegiul, iar tabel, baza_de_date, utilizator si parola
au semnificatiile cunoscute.
Sunt permise si forme similare ale comenzii REVOKE:
REVOKE privilegiu (coloane) ON tabel FROM utilizator; sau
REVOKE privilegiu (coloane) ON baza_de_date.* FROM utilizator;
Intre privilegiile posibile se numara urmatoarele:
• INSERT, care permite insertia randurilor care contin coloana specificata
• SELECT, care permite accesul la randurile care contin coloana
specificata
• UPDATE, care permite actualizarea randurilor care contin coloana
specificata De exemplu, pentru a permite unui utilizator sa obtina accesul la
o coloana, fara a o modifica, puteti folosi o secventa de comenzi similara cu
urmatoarea:
REVOKE ALL ON carte FROM php;
GRANT
SELECT(carteid, titlu, pret),
INSERT(carteid, titlu, pret),
UPDATE(carteid, titlu, pret)
ON carte TO php IDENTIFIED BY 'eusuntala';
REVOKE INSERT(pret) ON carte FROM php;
REVOKE UPDATE(pret) ON carte FROM php;
Retineti ca prima comanda revoca toate privilegiile de la nivelul tabelului;
in caz contrar, aceste privilegii le vor elimina pe cele situate la nivel
de coloana.
Caracteristica privilegiilor furnizata de MySQL este extrem de sofisticata si
furnizeaza mult mai multe optiuni. Pentru mai multe informatii, consultati manualul
SQL pe suport electronic, de la adresa www.mysql.com.
</Sfatul specialistului>
<Test „la minut">
• Care este numele tehnicii de modelare frecvent folosita in proiectarea
bazelor de date?
• Care este cardinalitatea relatiilor care trebuie sa fie inlocuite
la proiec¬tarea unei baze de date?
• Care este numele procesului de adaptare a unei baze de date la o serie
de reguli destinate a preveni aparitia erorilor comune de proiectare?
• Care este numele sub-limbajului SQL folosit pentru crearea bazelor de
date?
</Test „la minut">
<titlu>Accesul la datele dintr-o baza de date: interogarile SQL</titlu>
In afara de Data Definition Language, SQL include Data Manipulation Language*
(DML). DML va permite sa formati interogari, care obtin accesul la datele stocate
intr-o baza de date relationala si raporteaza aceste date. De asemenea,
puteti folosi DML pentru a insera, actualiza si sterge randurile dintr-un
tabel. Celelalte sectiuni ale acestui modul vor trata despre DML, iar sectiunea
de fata va aborda cea mai elementara forma de interogare: comanda SELECT simpla.
Cea mai simpla interogare posibila raporteaza toate coloanele din toate randurile
unui tabel. Interogarea are urmatoarea forma:
SELECT * FROM tabel;
unde tabel este numele tabelului la care se va obtine accesul. Formatul datelor
de iesire plaseaza fiecare rand al tabelului pe o linie separata si prezinta
coloanele intr-o ordine arbitrara. Datele de iesire includ numele coloanelor
si caractere simulate de desenare a liniilor, care separa coloanele. De exemplu,
ruland aceasta interogare asupra tabelului angajat se produc date de iesire
similare cu urmatoarele:
<tabel>
*angajatnr
*nume
*1
*George Washington
*3
*T. Jefferson
2 rows in set (0.00 sec)
</tabel>
<nota>
Raspunsuri la test
• Modelare E-R
• N:N
• Normalizarea bazelor de date
• Data Definition Language
*In traducere limbaj de manipulare a datelor. - N.T. </nota>
Daca doriti sa selectati numai anumite coloane sau sa raportati coloanele intr-o
anumita ordine, puteti folosi urmatoarea forma alternativa a comenzii SELECT:
SELECT coloana1, coloana2 FROM tabel;
unde tabel este numele tabelului, iar coloana1 si coloana2 sunt coloanele la
care se va obtine accesul si al caror continut va fi raportat. Puteti specifica
una, doua sau mai multe coloane; pur si simplu separati numele fiecarei coloane
de vecinii sai prin intermediul unei virgule. De exemplu, iata o interogare
care inverseaza ordinea coloanelor in comparatie cu interogarea anterioara:
SELECT nume, angajatnr FROM angajat;
In continuare, sunt prezentate datele de iesire caracteristice ale acestei
interogari:
<tabel>
*nume
*angajatnr
*George Washington
*1
*T. Jefferson
*3
2 rows in set (0.00 sec)
</tabel>
Deseori, este necesara numai raportarea acelor randuri care satisfac
un anumit criteriu. Clauza WHERE va permite sa specificati o conditie; randurile
care nu satisfac conditia nu sunt raportate. De exemplu, iata o interogare care
raporteaza un singur rand:
SELECT angajatnr, nume FROM angajat WHERE angajatnr=1;
Forma conditiilor folosite in sub-limbajul DML al limbajului SQL este
similara cu aceea a conditiilor PHP. Puteti folosi oricare din urmatorii operatori
relationali:
<tabel>
*operator
*descriere
*=
* Egalitate
*<>
* Inegalitate
*!=
* Inegalitate
*<
* Mai mic decat
*>
* Mai mare decat
*<=
* Mai mic sau egal cu
*=>
*Mai mare sau egal cu
</tabel>
Puteti compara valoarea unei coloane cu aceea a unei alte coloane, respectiv
valoarea unei coloane cu o valoare literala. Valorile literale sir SQL trebuie
sa fie incluse intre ghilimele simple, nu intre ghilimelele duble
permise de PHP.
<sugestie>
Cand unei coloane nu i-a fost repartizata nici o valoare, SQL ii
atribuie valoarea speciala NULL. De asemenea, programatorii pot atribui in
mod explicit valoarea NULL unei coloane. Comparatiile obisnuite cu valori NULL,
care folosesc operatorii de (in)egalitate, vor returna un rezultat fals. Totusi,
puteti folosi operatorul special <=>. care compara valorile tinand
cont de valoarea NULL. Daca folositi acest operator pentru a compara doua valori
NULL, se obtine un rezultat adevarat. </sugestie>
De asemenea, SQL include numerosi operatori de comparatie non-algebrici:
<tabel>
*operator
*descriere
* x BETWEEN y AND z
*Adevarat, daca valoarea lui x este cuprinsa intre valorile lui y si z.
* x LIKE y
* Adevarat daca valoarea lui x este echivalenta cu modelul y.
* x NOT LIKE y
*Adevarat daca valoarea lui x nu este echivalenta cu modelul y.
* x IN (y1, y2)
*Adevarat daca valoarea lui x este un membru al listei y1, y2. Lista poate contine
unul, doi sau mai multi membri.
* x NOT IN (y1, y2)
*Adevarat daca valoarea lui x nu este un membru al listei y1, y2. Lista poate
contine unul, doi sau mai multi membri.
* x IS NULL
*Adevarat daca x are valoarea NULL.
* x IS NOT NULL
*Adevarat daca x nu are valoarea NULL.
</tabel>
Sub-limbajul folosit pentru specificarea modelelor asociate operatorului LIKE
este diferit de cel folosit de PHP sau de shell-ul UNIX. Meta-caracterul % corespunde
unui numar de zero sau mai multe caractere, iar meta-caracterul _ corespunde
unui singur caracter. Modelele, ca si sirurile, sunt incluse intre ghilimele
simple. De exemplu, modelul '%ar%' corespunde oricarui sir care contine sub-sirul
'ar', inclusiv siruri precum 'ar', 'arc' si 'un zar'.
<Sugestie>
Pentru a plasa un caracter % sau _ intr-un sir test, folositi secventa
\% sau \_; ca in PHP, caracterul slash orientat inapoi determina
interpretarea celor doua caractere ca avand semnificatia lor literala,
nu ca meta-caractere. </Sugestie>
Ca si PHP, sub-limbajul DML din SQL va permite sa formati expresii logice care
combina expresiile relationale. Puteti folosi oricare din urmatorii operatori
logici:
<tabel>
*operator
*descriere
*AND
*Sl, adevarat daca ambii operanzi sunt adevarati
*OR
*SAU inclusiv, adevarat daca un operand este adevarat
*NOT
*NU, adevarat daca operandul este fals
</tabel>
De exemplu, urmatoarea interogare raporteaza randurile care au un numar
de angajat mai mare decat unitatea sau al caror nume include sub-sirul
'George':
SELECT angajatnr, nume FROM angajat
WHERE angajatnr>1 OR nume LIKE ’%George%’;
<Sfatul specialistului>
Intrebare: Operatorul SQL pentru identificarea echivalentei cu un model
nu foloseste sintaxa obisnuita a expresiilor regulate. Exista vreun mod de a
folosi in SQL expresii regulate?
Raspuns: Desi SQL este un limbaj standardizat, distribuitorii SGBD tind sa devieze
usor de la limbajul SQL sau sa-1 extinda. Astfel, fiecare SGBD accepta un dialect
SQL usor diferit de celelalte. Dialectul acceptat de MySQL include un operator
relational care executa comparatia cu o expresie regulata, dar nu toate sistemele
de gestiune a bazelor de date includ un asemenea operator.
Pentru a compara o valoare cu o expresie regulata in MySQL, folositi
urmatoarea forma: x REGEXP y unde x este valoarea care va fi testata, iar y este o expresie regulata, delimitata
prin ghilimele simple.
MySQL include multe alte extensii ale limbajului SQL. De exemplu, MySQL accepta
urmatorii operatori ca echivalent:
<tabel>
*Operator
*Echivalent
*AND
*&&
*OR
*||
*NOT
*!
</tabel>
Pentru a vedea si alte diferente fata de standardul SQL si extinderi ale acestuia,
consultati manualul MySQL pe suport electronic, la adresa www.mysql.com.
</Sfatul specialistului>
<Test „la minut">
• Care este comanda SQL folosita pentru a raporta datele dintr-o baza
de date?
• Mentionati clauza care va permite sa specificati randurile raportate
de o interogare.
• Precizati operatorul care va permite sa comparati o valoare sir cu un
model.
</Test „la minut">
<titlu>Modificarea datelor dintr-o baza de date</titlu>
Sub-limbajul SQL Data Manipulation Language include comenzi care va permit sa
inserati randuri noi intr-un tabel, sa actualizati una sau mai multe
coloane ale ran¬durilor existente in tabele, respectiv sa stergeri
randuri dintr-un tabel. Pentru a insera un nou rand intr-un
tabel, folositi comanda INSERT, care are urmatoarea forma:
INSERT INTO tabel VALUES (valoare1, valoare2);
unde tabel este numele tabelului la care se va adauga randul, valoare1
este valoarea pentru prima coloana din tabel, iar valoare2 este valoarea celei
de-a doua coloane din tabel. Se pot da mai mult sau mai putin de doua valori;
numarul valorilor date trebuie sa fie egal cu acela al coloanelor din tabel.
O coloana poate primi si valoarea NULL, cu exceptia situatiilor cand definitia
coloanei contine specificatii contrare.
<nota>
Raspunsuri la test:
• SELECT
• WHERE
• LIKE
</nota>
O forma mai populara a comenzii INSERT specifica numele coloanelor carora le
sunt atribuite valorile:
INSERT INTO tabel (coloana1, coloana2) VALUES (valoare1, valoare2);
In aceasta forma, coloana denumita coloana1 primeste valoarea valoare1,
iar coloana denumita coloana2 primeste valoarea valoare2. Ca in cazul
primei forme a comenzii INSERT, pot fi specificate mai mult, respectiv mai putin
de doua coloane si valori. Numarul coloanelor specificate trebuie sa fie egal
cu numarul valorilor specificate. Coloanele care nu sunt denumite in comanda
INSERT si care nu au o valoare prestabilita (DEFAULT) primesc valoarea NULL,
cu exceptia situatiilor cand valoarea respectiva nu este permisa; in
acest caz, comanda INSERT esueaza.
De exemplu, se poate folosi o comanda similara cu urmatoarea pentru a insera
un rand nou in tabelul angajat:
INSERT INTO angajat (angajatnr, nume) VALUES (4, ’James Monroe’);
Toate coloanele, cu exceptia coloanelor angajator si nume, vor primi valoarea
NULL.
<Sugestie>
Trebuie sa evitati utilizarea primei forme a comenzii INSERT. Adaugarea sau
stergerea coloanelor dintr-un tabel pot duce la o functionare defectuoasa a
acestei forme a comenzii, deoarece modul sau de operare depinde de echivalenta
secventiala intre valori si coloanele din tabel. </Sugestie>
Pentru a modifica valoarea unui rand sau mai multor randuri existente
intr-un tabel, emiteti o comanda UPDATE, care are urmatoarea forma:
UPDATE tabel SET coloana1=coloana1, coloana2=coloana2
WHERE conditie;
unde tabel este numele tabelului ale carui randuri urmeaza sa se modifice,
coloana1 este numele primei coloane care urmeaza a fi modificata, valoare1 este
valoarea care va fi repartizata in coloana1, coloana2 este numele celei
de-a doua coloane care urmeaza a fi modificata, valoare2 este valoarea care
va fi repartizata in coloana2, iar conditie identifica randul sau
randurile care urmeaza a fi actualizate. Poate fi actualizat un numar
mai mare sau mai mic de coloane. Daca urmeaza ca fiecare rand sa fie actualizat,
clauza WHERE poate fi omisa.
De exemplu, comanda urmatoare modifica numele asociat angajatului al carui atribut
angajator are valoarea 4 in James Monroe:
UPDATE angajat SET nume=’James Monroe’
WHERE angajatnr=4;
Urmatoarea comanda mareste salariul fiecarui angajat cu 10 procente:
UPDATE angajat SET salariu=1.1*salariu;
Pentru a sterge un rand dintr-un tabel, emiteti comanda DELETE, care
are urmatoarea forma:
DELETE FROM tabel WHERE conditie;
Daca vor fi sterse toate randurile tabelului, clauza WHERE poate fi omisa.
De exemplu, comanda urmatoare sterge randul din tabel asociat angajatului
al carui atribut angajator are valoarea 4:
DELETE FROM angajat WHERE angajatnr=4;
De asemenea, urmatoarea comanda sterge fiecare rand al tabelului angajat:
DELETE FROM angajat;
<Sugestie>
Comenzile INSERT, UPDATE si DELETE modifica valorile randurilor din tabel,
in general, nu este posibila recuperarea valorilor originale ale randurilor
din tabel dupa emiterea uneia dintre aceste comenzi. Ca atare, este important
sa realizati copii de siguranta ale bazelor de date si sa procedati cu atentie
la emiterea unor comenzi ca acestea. </Sugestie>
<Sfatul specialistului >
Intrebare: Exista vreo modalitate simpla de adaugare a mai multor randuri
intr-un tabel dintr-o baza de date?
Raspuns: Da. Puteti folosi urmatoarea forma modificata a comenzii INSERT, care
va permite sa specificati mai multe randuri ale unui tabel:
INSERT INTO tabel (coloana1, coloana2)
VALUES
(valoare1, valoare2),
(valoare3, valoare4),
(valoare5, valoare6);
Aceasta forma a comenzii va permite sa specificati grupuri de valori; fiecare
grup este inclus intre paranteze si separat de grupurile adiacente prin
intermediul unei virgule. Ca si in cazul formei obisnuite a comenzii INSERT,
numarul de coloane specificate trebuie sa corespunda cu acela al valorilor specificate
in fiecare grup; cu toate acestea, puteti specifica un numar nelimitat
de grupuri.
</Sfatul specialistului >
<Test „la minut">
• Scrieti o comanda SQL care insereaza un rand nou in tabelul
angajat. In noul rand, atributul angajator trebuie sa aiba valoarea
5, iar atributul nume trebuie sa aiba valoarea ,James Monroe".
• Scrieti o comanda SQL care mareste salariul fiecarui angajat cu 20 de
procente.
• Scrieti o comanda SQL care sterge randul din tabel in care
atributul angajator are valoarea 2. </Test „la minut">
<titlu>Sortarea, agregarea si gruparea</titlu>
Deseori, este important ca datele sa fie raportate intr-o anumita secventa.
Puteti specifica ordinea de raportare a rezultatelor interogarii folosind clauza
ORDER BY, care are urmatoarea forma:
ORDER BY valoare
Daca se vor folosi mai multe campuri de sortare, fiecare camp va
fi separat de vecinii sai prin intermediul unei virgule. Daca doriti sa indicati
o sortare descendenta, in locul uneia ascendente, specificati DESC dupa
valoare. De exemplu, pentru a ordona pe toti angajatii in functie de salariu,
de la cel mai mare la cel mai mic, respectiv dupa nume pentru un salariu dat,
puteti folosi urmatoarea interogare:
SELECT salariu, nume FROM angajat
ORDER BY salariu DESC, nume;
Pentru a include numai pe angajatii care au un salariu mai mare de 50000 USD,
adaugati o clauza WHERE la comanda SELECT:
SELECT salariu, nume FROM angajat
WHERE salariu>50000
ORDER BY salariu DESC, nume;
SQL include functii care va permit sa raportati valori agregate, precum un
numar al randurilor tabelului. Iata cele mai importante functii de agregare:
<tabel>
*Functie
* Descriere
*count(*)
* Numarul randurilor din tabel.
*count(coloana)
* Numarul randurilor din tabel care contin o valoare diferita de NULL
in coloana specificata.
*count(distinct coloana)
* Numarul valorilor distincte diferite de NULL care apar in coloana specificata.
*avg(coloana)
* Valoarea mijlocie (medie) a coloanei numerice specificate.
*min(coloana)
* Valoarea minima din coloana specificata.
*max(coloana)
* Valoarea maxima din coloana specificata.
*sum(coloana)
*Suma valorilor din coloana specificata.
</tabel>
De exemplu, interogarea urmatoare raporteaza numarul angajatilor si salariul
mediu al acestora:
SELECT count(*), avg(salariu) FROM angajat;
<nota>
Raspunsuri la test:
• INSERT INTO angajat (angajator, nume)
VALUES (5, 'James Monroe');
• UPDATE angajat SET salariu=1.2*salariu;
• DELETE FROM angajat WHERE angajatnr=2;</nota>
Datele de iesire vor contine o singura linie, deoarece datele au fost comasate.
Clauza SQL AS specifica un nume nou pentru o coloana sau expresie. Numele specificat
este folosit ca titlu in rapoartele SQL. Clauza AS este utila in
lucrul cu functiile de agregare. De exemplu, interogarea urmatoare poate fi
rescrisa pentru a include o clauza AS, dupa cum urmeaza:
SELECT count(*) AS Angajat_Numar, avg(salariu) AS Salariu_Mediu
FROM angajat;
Rezultatul unei asemenea interogari se poate prezenta astfel:
<tabel>
*Angajat_Numa
*Salariu_mediu
*2
*63250.000000
1 row in set (0.00 sec)
</tabel>
Sa presupunem ca doriti sa afisati numarul angajatilor din fiecare departament.
Rezultatul unei asemenea interogari va contine o linie pentru fiecare departament,
in loc de o linie pentru fiecare angajat. Clauza GROUP BY specifica o
asemenea inte¬rogare. Clauza are urmatoarea forma:
GROUP BY coloana-sortare
unde coloana-sortare este numele sau valoarea unei coloane, specificata intr-o
clauza ORDER BY, care trebuie sa urmeze dupa clauza GROUP BY.
De exemplu, interogarea urmatoare raporteaza numarul angajatilor si salariul
m