Sunteți pe pagina 1din 22

Lecia 1

Crile din magazinul nostru virtual ar trebui aranjate, la fel ca ntr-o librrie, dup domeniul cruia i aparin, evitnd s punem laolalt romanele de aventuri cu manualele colare i crile tehnice spre exemplu. Trebuie s organizm datele, n aplicaia noastr, n aa fel nct s putem regsi uor crile dup domeniu, s le ordonm dup titlu sau s le alegem pe cele aparinnd unui anumit autor. Soluia cea mai flexibil, care s corespund acestor cerine, este baza de date populat cu tabelele aferente.

Colecii de date
Prin definiie, baza de date este o colecie organizat. Cartea de telefon ar putea fi un astfel de exemplu sau programul TV dintr-o anumit publicaie. n cartea de telefon gsim numele si prenumele abonatului, adresa i numrul de telefon, toate acestea ordonate dup nume pentru a cuta mai uor o anumit persoan. Dac am avea cartea de telefon n format electronic, ntr-o tabel din baza de date, am putea face, spre exemplu, o ordonare dup numrul de telefon n ordine cresctoare pentru a afla cine are cel mai mic numr. Am putea de asemenea s aflm ci abonai au nume care ncep cu T, ci dintre ei au prenumele Ion, numrul de abonai din ora, strada pe care sunt cele mai multe posturi telefonice i aa mai departe. n programul TV informaiile au urmtoarea structur: canalul, ora difuzrii, numele programului. Acestea sunt de obicei ordonate dup canal i ora difuzrii, astfel: Canalul A 16:00 Desene animate. Jack si vrejul de fasole 18:00 Film: Tcerea mieilor 19:00 tiri 20:00 Film: Matrix 22:00 Muzica Canalul B 16:00 Muzica 17:00 Documentar Al doilea rzboi mondial 18:00 tiri 19:00 Desene animate: Mica sirena 20:00 Talkshow financiar 21:00 Film serial: Star Trek(ep 140) 16:00 Program pentru copii Canalul C 17:00 Desene animate Dexter 18:00 Film serial VIP (ep. 101) 19:00 tiri 20:00 Film: Lord of the Rings 22:00 Documentar Marele alb

Lecia 1

S ne imaginm c tiem cu foarfeca din ziar fiecare nume de program i or de difuzare. Atunci ne-am putea ordona programele dup ora difuzrii astfel nct s putem distinge mai uor ce ne intereseaz ntr-un anume interval orar: Ora 16:00 Nume program Desene animate Jack si vrejul de fasole Muzica Program pentru copii Documentar Al doilea rzboi mondial Desene animate: Dexter Film: Tcerea mieilor tiri Film serial VIP (ep. 101) tiri Desene animate tiri Film: Matrix Talkshow financiar Film: Lord of the Rings Film serial: StarTrek (ep.140) Canalul B Muzica Documentar. Marele alb Canal Canalul A Canalul B Canalul C Canalul B Canalul C Canalul A Canalul B Canalul C Canalul A Canalul B Canalul C Canalul A Canalul B Canalul C Canalul A Canalul C

17:00 18:00 19:00 20:00 21:00 22:00

Avnd o baz de date scpm i de ziar i de foarfec deoarece ne putem ordona programele dup plac, putem alege s vizualizm doar programele ntre ora 17 i ora 22, putem afia pe ecranul calculatorului doar filmele din program i aa mai departe.

Ce se ntmpl n interiorul bazei de date


Am definit baza de date ca i colecie organizat. O baz de date este compus din unul sau mai multe tabele (tables) care, la rndul lor, sunt formate din nregistrri dispuse n cmpuri (fields). Dac ai lucrat cu un program de calcul tabelar Excel, baza de date neo putem imagina ca fiind documentul ce conine mai multe foi de lucru (tabelele), cmpurile ca fiind coloanele tabelelor iar o nregistrare oarecare ca fiind un rnd din tabel. S lum exemplul crii de telefon. Baza de date va conine un singur tabel cu 4 cmpuri: nume, prenume, adres si numr de telefon. nume Andu Baciu Creu Fulg Zinc prenume Paul Bianca Mihai Ramona Gheorghe adresa Lunii 29 Viforului 15 Muncii 4 Republicii 14 Bd. Grii 2A numr de telefon 4567893 3456874 2154636 1445328 6522554

Lecia 1

Coninutul fiecrei linii, se numete generic nregistrare (record). Din prima nregistrare aflm c Andu Paul locuiete pe strada Lunii 29 i are numrul de telefon 456789. Valoarea cmpului nume al primei nregistrri este Andu, iar valoarea cmpului prenume a celei de-a doua nregistrri este Bianca. Baza de date a departamentului contabilitate a unui magazin de papetrie va avea mai multe tabele care s conin tipuri diferite de date. Nici unei contabile nu i va fi util s aib furnizorii amestecai cu stocurile i cheltuielile, ci va dori s aib aceste date separate, dar totodat puse laolalt n acelai loc. Ea va avea nevoie de un tabel Stoc care s conin dou cmpuri: nume produs Creioane Pixuri Plicuri A4 nr. buc. in stoc 3511 5000 275

Va mai avea nevoie i de un tabel Cheltuieli cu urmtoarea structur: produs sau serviciu Decoraiuni interioare Reparaii Jaluzele cost 5.000.000 lei 700.000 lei 12.000.000 lei data 20.12.2002 03.01.2003 04.01.2003

Pe lng acestea mai sunt necesare tabelele: salarii i vnzri, pentru ca la sfritul anului s centralizeze datele din aceste tabele pentru bilanul contabil. Din acest exemplu putem observa c exist cazuri n care avem nevoie de mai multe tabele pentru organizarea informaiei, tabele pe care le inem ntr-o singur baz de date pentru o accesare mai uoar sau pentru a intermedia relaii ntre ele. O baz de date poate conine, la un moment dat, un numr uria de tabele i nregistrri. Din informaiile de pe site-ul www.mysql.com putem afla c exist la ora actual baze de date pe MySQL Server cu peste 60.000 de tabele i peste 5 miliarde de nregistrri.

SQL
SQL, acronimul pentru Structured Query Language, este limbajul standard pentru comunicarea cu bazele de date. Comenzile SQL sunt folosite pentru a interaciona cu baza de date (spre exemplu: s se adauge, s se modifice sau s tearg date). Pot fi enumerate aici i alte sisteme de baze de date care folosesc SQL ca: Microsoft SQL Server, Access, Oracle, Sybase, etc.

MySQL
MySQL este cel mai popular sistem de management pentru baze de date relaionale. Este de menionat faptul c este Open Source (poate fi folosit fr s fim nevoii s pltim vreo sum de bani). MySQL Server a fost creat pentru a lucra cu baze de

Lecia 1

date mai rapid dect soluiile existente deja i este folosit de ani buni n medii foarte solicitante. ntr-o baz de date relaional datele sunt stocate n mai multe tabele separate, fiind mbuntite astfel, viteza i flexibilitatea. Tabelele pot fi legate, ntre ele, prin relaii definite de noi, fiind astfel posibil s combinm la cerere datele din mai multe tabele.

Baza de date
Pentru a ne putea construi o baz de date trebuie ca serverul MySQL s fie pornit. n continuare, va trebui s folosim o aplicaie cu ajutorul creia s comunicm cu serverul. Aplicaia se numete simplu mysql.exe i se gsete in acelai director: c:\mysql\bin\ . Vom intra n command prompt apsnd pe Start, apoi pe Run i scriind command(pe unele SO se pot folosi prescurtri cum ar fi cmd) n cmpul destinat programului ce urmeaz s fie rulat. O dat aflai n linia de comand, scriem: c: \mysql\bin\mysqld.exe c: \mysql\bin\mysql.exe -p -u root. iar cnd ni se cere parola, apsam tasta ENTER. Dac serverul nu este pornit vom primi mesajul de eroare Can't connect to MySQL server on 'localhost' . Serverul de MySQL, ca orice server care se respect, ofer posibilitatea de a avea mai muli posesori de date pe acelai sistem, fiecare cu drepturile lui. Astfel, serverul unui ISP spre exemplu va putea fi folosit de mai muli utilizatori, fiecare avnd mai multe baze de date i neputnd s vad ce au ceilali utilizatori ai aceluiai server. Utilizatorul implicit (cel cu drepturi depline) este root, iar parola nu conine nici un caracter, adic este goal. Vom lucra cu aceste date pentru nceput dar poate fi consultat manualul MySQL pentru a afla cum pot fi adugai utilizatori noi sau cum se poate schimba o parol n MySQL.

SHOW
Odat autentificai vom putea comunica cu serverul MySQL folosind comenzi SQL. Trimiterea unei comenzi SQL ctre serverul de baze de date se mai numete i interogare. S ncepem cu prima noastr interogare aflnd totodat dac exist creat deja vreo baz de date pe server: SHOW DATABASES; Am ncheiat interogarea cu punct i virgul deoarece toate comenzile (cu excepia comenzilor QUIT i USE) trebuie ncheiate astfel pentru a semnala serverului c am terminat de scris propoziia i c poate trece la procesarea cererii. Exist cazuri n care o interogare poate fi foarte lung i atunci ar trebui separat pe mai multe rnduri. MySQL d mesaj de eroare dac observ c propoziia este neterminat aa c e bine s nu uitm s ncheiem interogrile cu punct i virgul. S inspectm una din bazele de date de pe serverul pe care lucrm. Pentru a face acest lucru, trebuie s-i spunem serverului, cu ce baz de date dorim s interacionm:

Lecia 1

USE test Vom primi mesajul Databasc changed iar baza de date 'test' va rmne cea n care vom face interogrile pn la deconectarea de la server sau dac decidem s folosim o alt baz de date, cu aceeai comand: USE alta_baza_de_date

Sortarea unei baze de date ca fiind cea curent nu ne mpiedic totui s accesm tabele din alte baze de date n forma nume_baz_de_date.nume_tabel. Comanda USE este pstrat pentru compatibilitatea cu Sybase. Comanda SHOW o vom folosi i pentru a vedea ce tabele exist n baza de date test:

SHOW TABLES
O alt utilizare a lui SHOW este: SHOW COLUMNS care afieaz informaii despre coloanele unui tabel.

CREATE i DROP
Vom crea o baz de date special pentru site-ul magazinului nostru de cri. Vom scrie n linia de comand: CREATE DATABASE librarie; Serverul ne afieaz Query OK deci, baza de date librarie a fost creat. Va trebui s mai spunem serverului c aceasta este baza de date cu care urmeaz s interacionm n continuare: USE librarie Am putea s folosim interogarea SHOW TABLES, ns nu ne-ar ajuta prea mult, asta pentru c noua baz de date creat nu are nc nici un tabel. S crem, unul: CREATE TABLE tabel_test (camp_test TEXT); Tem: executai comenzile SHOW TABLES i SHOW COLUMNS pentru noua baz de date i tabelul proaspt creat. S analizm cuvnt cu cuvnt, propoziia: CREATE TABLE tabel_test (camp_test TEXT); nseamn creeaz tabelul tabel_test cu un cmp numit camp_text al crui tip este TEXT. S crem nc un tabel, cu trei coloane:

Lecia 1

CREATE TABLE tabel_test2 (camp1 TEXT, camp2 INT, camp3 TINYINT); S le analizm: prima caracteristic, Field(camp1), este numele cmpului; a doua, Type, este tipul de date coninut de cmp. TEXT nseamn c datele de pe coloana respectiv vor fi de tip text, INT nseamn c vor fi numere ntregi iar TINYINT specific faptul c n coloana respectiv pot fi introduse doar numere cuprinse ntre -128 i 127;

Revenind la magazinul nostru de cri, s recapitulm datele de care avem nevoie n site i s ncercm s le organizm logic. Fiecare carte are un autor, un titlu i o scurt descriere. Toate aceste informaii sunt de tip text, deci aa vor fi i tipurile de cmpuri aferente lor. S crem tabela carti: CREATE TABLE carti (autor TEXT, titlu TEXT, descriere TEXT); n cazul n care nu a fost semnalat nici o eroare, tabela carti a fost creat, moment n care nu este populat cu nici o informaie. Verificri, despre tabela carti pot fi fcute cu una din comenzile: SHOW TABLE nume_tabel sau SHOW COLUMNS FROM nume_tabel. Pentru a terge o baz de date, un tabel, o coloan dintr-un tabel sau un index se folosete comanda DROP astfel: DROP TABLE tabel_test; DROP DATABASE librarie; Dei MySQL are suport pentru diacritice i setul de caractere 8859-2, este preferabil s nu folosii diacritice n numele bazelor de date, tabelelor sau cmpurilor. De asemenea, nu pot fi folosite ca nume de tabel sau de cmp cuvintele rezervate (nume de funcii, tipuri de caractere din MySQL precum create, drop sau column). Ar mai trebui s tim c putem folosi ca i nume de tabele, nume care conin spaii dar n practic trebuiesc ncadrate aceste nume ntre back-ticks `` (semnul back-tick se afl sub tasta Escape): CREATE TABLE tabel al crui nume are spatii (camp1, TEXT); SHOW COLUMNS FROM tabel al carui nume are spatii; SELECT camp1 FROM tabel al crui nume are spatii;

INSERT
S introducem cteva date n tabelul carti. Comanda folosit este INSERT iar sintaxa este: INSERT INTO tabel(camp1, camp2, camp3) VALUES(val1, val2, val3);

Lecia 1

Aceast comand s-ar traduce astfel introdu val1 n camp1, val2 n camp2 i val3 n camp3, iar n format tabelar ar arta n felul urmtor: camp1 val1 camp2 val2 camp3 val3

S exersm comanda INSERT: INSERT INTO carti (autor, titlu, descriere) VALUES (William Shakespeare, Romeo si Julieta`, Cea mai frumoas poveste de dragoste a tuturor timpurilor); Am pus apostrof la nceputul i sfritul fiecrei valori ce urmeaz a fi introduse pentru a stabili c acela este un text unitar, un string de introdus n cmpul respectiv. S ne imaginm cum ar interpreta serverul comanda noastr dac am scrie numele autorului n forma Shakespeare, William. Atunci textul interogrii ar fi: INSERT INTO carti(autor, titlu) VALUES(Shakespeare, William, Hamlet) i serverul MySQL ne-ar returna urmtoarea eroare: Column count doesn't match value count at row 1 deoarece se ateapt ca pentru dou coloane s aib de introdus tot dou valori separate prin virgul, nu trei. Dac am fi specificat c vrem s introducem valori n toate cele trei coloane am fi primit alt mesaj de eroare deoarece MySQL nu ar fi recunoscut textul 'Shakespeare' ca fiind string i s-ar fi oprit din execuie. Dac dorim, putem s omitem una din coloane unde nu adugm nimic n cmpul descriere: INSERT INTO carti(autor, titlu) VALUES (William Shakespeare,Hamlet); Sintaxa lui INSERT poate fi simplificat dac lum n calcul toate cmpurile tabelului deoarece le putem omite, menionnd doar valorile ce urmeaz a fi adugate ca n exemplul urmtor: INSERT INTO carti VALUES(Mihai Eminescu, Poezii, Cele mai frumoase poezii ale poetului naional); Observm c nu am mai specificat coloanele n care urmeaz s introducem date, sintaxa fiind astfel mult simplificat. Dac dorim s beneficiem de sintaxa prescurtat pentru INSERT dar nu avem o valoare pentru un cmp, putem s nu punem nimic ntre apostrof-urile care delimiteaz valoarea respectiv sau un text gol n cmpul descriere, astfel: INSERT INTO carti VALUES(Mihai Eminescu, Poezii, volumul 2, ); INSERT INTO carti VALUES(Mihai Eminescu, Poezii, volumul 3, ); INSERT INTO carti VALUES(Alexandru Mitru, Legendele Olimpului, );

Lecia 1

INSERT INTO carti VALUES(George Cosbuc, Fire de tort - Poezii, ); INSERT INTO carti VALUES(Mihai Eminescu, Geniu Pustiu, ); Tem: Adugai, folosind comanda INSERT, nc 5 cri n tabel specificnd titlul, autorul i eventual o scurt descriere.

Tipuri de date
Tipurile de date care apar n coloanele MySQL ar putea prea o complicaie inutil la prima vedere. Oare, nu am putea s adugm datele n ce form avem nevoie? Lucrurile nu stau chiar aa. MySQL aloc spaiu pe disc n funcie de tipul de date specificat de utilizator. Dac n tabelul salariai avem o coloan pentru numrul de zile de concediu legal o vom seta ca fiind TINYINT deoarece aceasta este valoarea numeric n care se ncadreaz (un salariat nu va avea mai mult de 127 de zile de concediu pe an!). Pentru fiecare nregistrare n coloana zile_concediu MySQL va aloca 1 byte de memorie, indiferent dac un angajat are 2 zile de concediu i altul are 18. Dac acelai cmp l setm ca INT, MySQL va aloca fiecrei nregistrri pentru coloan 4 bytes, indiferent de numrul de zile de concediu introduse i astfel pentru fiecare nregistrare se vor pierde 3 bytes. Acesta este doar un exemplu, dar ce se ntmpl dac avem o baz de date cu 10 milioane de nregistrri i atunci pierderea a 3 bytes la fiecare nregistrare se traduce n cteva zeci de MB de spaiu. S analizm tipurile de date n baze de date MySQL, spaiul pe care l ocup precum i valorile minime i respectiv maxime pe care le pot avea. Valori numerice: Tip
TINYINT SMALLINT MEDIUMINT INT BIGINT

Bytes
1 2 3 4 8

De la
-128 -32768 -8388608 -2147483648 - 9223372036854775808

binar
(1000 0000 - 0111 1111)

Pn la

127 32767 8388607 2147483647 9223372036854775807

Toate tipurile de mai sus au un atribut opional (nestandard), UNSIGNED. Poate fi folosit acest atribut n definirea tipului de date al unei coloane atunci cnd se dorete s conin doar valori pozitive. Un cmp de tip TINYINT va putea conine numere ntre -128 i 127 n timp ce cmpul, TINYINT UNSIGNED va putea avea valori ntre 0 i 255. La fel, pentru SMALLINT valorile sunt de la -32768 pn la 32767 n timp ce pentru SMALLINT UNSIGNED ele pot fi ntre 0 i 65535. Dac ntr-un cmp declarat TINYINT are valori ntre -128 i 127 vei ncerca s introducei o valoare mai mic de -128 ea va fi convertit n cea nai mic valoare admis, -128. Dac se ncearc introducerea unei valori mai mari de 127 ea va fi convertit n cea mai mare valoare admis de tipul cmpului, adic 127 n acest caz.

Lecia 1

Dat/timp:
Column type DATETIME DATE TIMESTAMP TIME YEAR Format 'YYYY-MM-DD hh:mm:ss' 'YYYY-MM-DD' YYYYMMDDhhmmss 'hh:mm:ss' 'YYYY'

Tipul de cmp TIMESTAMP ofer posibilitatea de a data automat operaiile de tip INSERT i UPDATE. El este compus implicit din 14 caractere pentru formatul 'YYYYMMDDhhmmss' dar putem s specificm la crearea unui tabel c dorim s conin mai puine caractere;

TIMESTAMP
Column type
TIMESTAMP(14) TIMESTAMP(12) TIMESTAMP(10) TIMESTAMP(8) TIMESTAMP(6) TIMESTAMP(4) TIMESTAMP(2)

Display format
YYYYMMDDHHMMSS' YYMMDDHHMMSS' YYMMDDHHMM YYYYMMDD YYMMDD YYMM YY

Stringuri (iruri)
Tipurile de string-uri n MySQL sunt: BLOB, TEXT, CHAR, VARCHAR, ENUM i SET. n tabelul urmtor putem vedea mrimea maxim admis pentru cele mai folosite dintre ele precum i spaiul alocat pe disc pentru fiecare: Tip
TINYTEXT sau TINYBLOB TEXT or BLOB MEDIUMTEXT or MEDIUMBLOB LONGBLOB

Mrime maxim
2^8-1 2^16-1 (64K-1) 2^24-1 (16M-1) 2^32-1 (4G-1)

Bytes
255 65535 16777215 4294967295

Cmpul de tip BLOB poate conine o cantitate variabil de informaie, similar cu TEXT ns diferit printr-un singur aspect: cutarea ntr-un cmp BLOB este case sensitive (se face diferen ntre majuscule i minuscule), iar ntr-un cmp TEXT nu. Tipul VARCHAR este similar tipului TEXT cu deosebirea c ntr-o coloan de tip VARCHAR putem specifica numrul maxim de caractere admis.

Lecia 1

SEELECT
Acum c avem baza de date, avem i cteva date introduse, cum putem vedea aceste date? Pentru aceast problem folosim comanda SELECT, cea mai important i totodat folosit comand SQL, observnd cteva din utilizrile ei n exemplele urmtoare. Am aflat cum putem vedea ce tabele sunt ntr-o baz de date, acum putem s aflm i ce informaii conine un tabel. S lum primul tabel creat i s afim datele coninute in acesta: SELECT * FROM tabel_test; va fi returnat urmtorul mesaj: Empty set (0.17 sec) Empty set nseamn c tabelul nu conine date, e gol. Ceea ce este scris ntre paranteze reprezint secundele care i-au luat server-ului ca s returneze un rezultat. S ncercm cu cellalt tabel, n care tim sigur c am introdus date i s vedem cum erat acestea: SELECT * FROM carti; Acum putem vedea foarte clar structura i coninutul tabelului. Asteriscul (*) din comanda SELECT * FROM carti; este echivalentul lui tot/toate", iar comanda s-ar traduce astfel: afieaz toate cmpurile din tabelul carti". Asteriscul l putem nlocui cu numele unui cmp pentru a vedea doar coninutul acelui cmp, astfel: SELECT titlu FROM carti; ne va afia doar coninutul cmpului titlu, astfel: titlu Hamlet Hamlet Poezii Poezii, volumul 2 Poezii, volumul 3 Legendele Olimpului Fire de tort Poezii Geniu pustiu

Se poate face o selecie astfel nct s fie afiate mai multe coloane, specificate de noi, n orice ordine dorim (nu neaprat n ordinea n care se afl n tabel), ca n interogarea urmtoare unde afim coloanele titlu i autor: SELECT titlu, autor FROM carti;

10 1

Lecia

titlu Hamlet Hamlet Poezii Poezii, volumul 2 Poezii, volumul 3 Legendele Olimpului Fire de tort - Poezii Geniu pustiu

autor William Shakespeare William Shakespeare Mihai Eminescu Mihai Eminescu Mihai Eminescu Alexandru Mitru George Cosbuc Mihai Eminescu

Putem afia crile pentru care cmpul descriere este gol, astfel: SELECT * FROM carti WHERE descriere = "";

autor William Shakespeare William Shakespeare Mihai Eminescu Mihai Eminescu Mihai Eminescu Alexandru Mitru George Cosbuc Mihai Eminescu

titlu Hamlet Hamlet Poezii Poezii, volumul 2 Poezii, volumul 3 Legendele Olimpului Fire de tort - Poezii Geniu pustiu

descriere

Avem suficiente date pentru a afla cteva utilizri noi i foarte interesante ale comenzii SELECT. Putem aduga condiii de selecie i putem astfel alege s ne fie afiate doar titlurile crilor lui Mihai Eminescu, astfel: SELECT titlu FROM carti WHERE autor='Mihai Eminescu';

titlu Poezii Poezii, volumul 2 Poezii, volumul 3 Geniu pustiu


S afim toate volumele de poezii din baza de date, indiferent de autor. Dac executm interogarea: SELECT * FROM carti WHERE titlu=Poezii ; va returna doar cartea al crui titlu este chiar "Poezii", nelundu-le n considerare i pe celelalte:
11 1 Lecia

autor Mihai Eminescu

titlu Poezii

Descriere Cele mai frumoase poezii ale poetului national

Folosind condiia: titlu = 'Poezii', nu vor fi afiate volumele 2 i 3 din colecia de poezii de Mihai Eminescu i nici cartea intitulat Fire de tort - Poezii" de Cosbuc. Dac vrem s obinem toate crile care conin secvena Poezii" oriunde n titlu putem face acest lucru nlocuind egalitatea cu operatorul LIKE i folosind wildcarduri(%). S vedem cum funcioneaz LIKE mpreun cu wildcardul %: SELECT autor, titlu FROM carti WHERE titlu LIKE 'poezii%' ; Vor fi afiate toate nregistrrile n care titlul crii ncepe cu secvena "poezii". autor Mihai Eminescu Mihai Eminescu Mihai Eminescu titlu Poezii Poezii, volumul 2 Poezii, volumul 3

MySQL trateaz toate valorile dintr-un cmp de tip TEXT ca fiind caseinsensitive astfel nct nu va trebui s inei cont de literele mari sau mici atunci cnd v referii ntr-o interogare la valoarea unui cmp. Comanda: SELECT * FROM carti WHERE titlu LIKE '%poezii'; va afia toate nregistrrile n care titlul crii se termin cu secvena poezii": volumele Poezii de Mihai Eminescu i Fire de tort - Poezii de George Cosbuc. Similar, SELECT * FROM carti WHERE titlu LIKE '%poezii%'; va afia toate nregistrrile n care titlul crii conine secvena "poezii" oriunde n cadrul textului. Putem extinde comanda SELECT pentru a aduga un nou criteriu de selecie. Dac dorim s alegem toate crile cu poezii de Mihai Eminescu fr s ne fie afiat i romanul scris de acesta sau cartea de poezii a lui George Cosbuc, vom trimite ctre tabela din baza de date o interogare cu dou criterii: "returneaz-mi toate nregistrrile unde autorul este Mihai Eminescu i titlul crii conine secvena poezii". SELECT * FROM carti WHERE autor=Mihai Eminescu AND titlu LIKE '%poezii%'; va afia toate nregistrrile n care titlul crii conine cuvntul poezii" oriunde n cadrul textului.

12 1

Lecia

autor
Mihai Eminescu Mihai Eminescu Mihai Eminescu

titlu
Poezii Poezii, volumul 2 Poezii, volumul 3

descriere
Cele mai frumoase poezii ale poetului national

Dac vrem s alegem toate crile care nu sunt scrise de Mihai Eminescu folosim operatorul de inegalitate (semnul != opusul lui =): SELECT autor, titlu :FROM carti WHERE autor != "Mihai Eminescu" ;

Tem: afiai toate titlurile crilor de William Shakespeare;


- afiai toate titlurile cartilor care conin litera T oriunde n textul titlului; - afiai doar titlurile crilor ale cror nume de autor se termin cu litera U; - afiai numele tuturor autorilor care nu se termin cu litera U; Putem folosi ORDER BY pentru a ordona rezultatele unei selecii, cresctor sau descresctor, n funcie de coloana aleas pentru ordonare. Iat spre exemplu, cum putem afia autorii din tabel n ordine cresctoare: SELECT autor FROM carti ORDER BY autor ASC; autor Alexandru Mitru George Cosbuc Mihai Eminescu Mihai Eminescu Mihai Eminescu Mihai Eminescu William Shakespeare William Shakespeare Putem avea mai multe criterii de ordonare, ca n exemplul urmtor unde ordonarea se face dup autor ASC iar pentru fiecare autor crile sunt ordonate dup titlu DESC: SELECT autor, titlu FROM carti ORDER BY autor ASC, titlu DESC; Putem afla cte nregistrri sunt pentru un criteriu de selecie cu ajutorul funciei count(). Putem astfel afla cte nregistrri avem n tabel: SELECT count(*) FROM carti; +------------+ | count(*) | +------------+ | 8 | +------------+
13 1 Lecia

sau, cte nregistrri sunt n tabel al cror cmp 'autor' este 'Mihai Eminescu': SELECT count (*) FROM carti WHERE autor='Mihai Eminescu'; +-----------+ | count(*) | +-----------+ | 4 | +-----------+ Putem "grupa" cu ajutorul instruciunii GROUP BY rezultatele astfel nct sa nu vedem duplicatele i s vedem doar valorile unice. Folosind GROUP BY, s vedem ce autori avem nregistrai i s i ordonm cresctor: SELECT autor FROM carti GROUP BY autor ORDER BY autor ASC; Autor Alexandru Mitru George Cosbuc Mihai Eminescu William Shakespeare Pentru a limita numrul de rezultate returnate, folosim instruciunea LIMIT. Dac avem 10.000 de nregistrri i nu dorim s vedem dect primele 3, folosim LIMIT n felul urmtor: SELECT * FROM carti LIMIT 0, 3; Dac dorim s vedem nregistrrile de la 3 la 7: SELECT * FROM carti LIMIT 3, 4; iar pentru nregistrrile de la 10 la 14: SELECT * FROM carti LIMIT 10,5; Este de remarcat faptul c primul numr dup LIMIT reprezint nregistrarea de la care se ncepe afiarea iar al doilea numr este numrul de nregistrri ce urmeaz a fi returnate.

DELETE
Comanda DELETE se folosete pentru tergerea nregistrrilor dintr-un tabel (reamintim c pentru tergerea tabelelor respectiv a bazelor de date se folosete comanda DROP). Sintaxa este urmtoarea: DELETE FROM tabela WHERE conditii;.

14 1

Lecia

Aa cum putem afia doar nregistrrile ce corespund condiiilor noastre, la fel putem condiiona i tergerea lor n funcie de criteriile specificate: S E L E C T * FROM carti WHERE autor='Mihai Eminescu'; afieaz toate nregistrrile din tabelul carti n care n cmpul autor apare cuvntul Mihai Eminescu, n timp ce: DELETE FROM carti WHERE autor='Mihai Eminescu'; va terge din tabel toate nregistrrile care conine n cmpul autor cuvntul Mihai Eminescu\, lsndu-le pe celelalte neatinse. Observm dou lucruri: n primul rnd, asteriscul fiind inutil a disprut din comanda DELETE. MySQL va terge un rnd (o nregistrare), dar nu va putea s tearg (logic) una sau mai multe coloane aparinnd unei nregistrri. n al doilea rnd, se observ c, sintaxa pentru tergere seamn cu sintaxa pentru selecie. La fel ca n comanda SELECT se pot folosi mai multe condiii putnd terge toate nregistrrile unde cmpul autor este Mihai Eminescu i titlul crii conine cuvntul poezii. DELETE FROM carti WHERE autor='Mihai Eminescu' AND titlu LIKE '%poezii%';

Atenie!
DELETE FROM carti; Aceast comand nu o vom pune n aplicare nainte de a ne gndi nc o dat despre ce vrem s facem. Este echivalentul tergerii tuturor nregistrrilor din tabela carti.

UPDATE
Atunci cnd vrem s modificm coninutul unei nregistrri nu este nevoie s o tergem i s o adugm in varianta nou, putem folosi UPDATE cu urmtoarea sintaxa: UPDATE table SET coloana1=noua valoare a coloanei 1, coloana2=noua voloare a coloanei 2 WHERE conditii; UPDATE modific coninutul unuia sau mai multor cmpuri n funcie de condiiile specificate. S modificm spre exemplu din coloana autor toate nregistrrile care conin numele Mihai Eminescu cu nregistrri care s conin numele M. Eminescu. Dup schimbare, pentru a observa modificarea, executai comanda: SELECT * FROM carti;

15 1

Lecia

Condiiile pot fi extinse la fel ca n sintaxa SELECT. n urmtoarea interogare vom modifica cmpul descriere al tuturor nregistrrilor al cror titlu conin cmpul poezii iar cmpul descriere este gol (). UPDATE carti SET descriere=carte de Poezii WHERE titlu LIKE %poezii% AND descriere=; Astfel toate crile fr descriere() al cror titlu coninea cuvntul poezii au acum descrierea Carte de poezii.

ALTER TABLE
ALTER TABLE ne permite s schimbm structura unui tabel existent. Putem aduga sau terge coloane i indeci, putem redenumi coloane sau chiar tabelul n sine i putem schimba tipul de date coninut de o coloan. S adugm n tabelul carti o coloan, pe care o numim data, n care dorim s stocm data adugrii crii. Acest cmp ne va fi util atunci cnd vom afia vizitatorilor noutile magazinului virtual pe prima pagin. El corespunde datei la care acesta a ajuns pe rafturile virtuale ale magazinului nostru adic, data nregistrrii acesteia n tabel. Cele mai noi 10 titluri ale crilor, nregistrate n magazinul virtual, le aflm folosind interogarea: SELECT titlu FROM carti ORDER BY data DESC LIMIT 0,10; Sa adugm noua coloan la sfritul tabelului. ALTER TABLE carti ADD dat TEXT; S presupunem c am scris greit numele coloanei i dorim s-o redenumim din dat n data. Mai mult, ne aducem aminte c exist n declaraii tipul DATE iar o dat cum este 10-11-2005 ne-ar putea fi mai util dac s-ar afla intr-un cmp de tip DATE dect intr-un cmp de tip TEXT aa c, vom modifica i tipul de date al noii coloane. Pentru cele dou modificri vom proceda astfel: ALTER TABLE carti CHANGE dat data DATE; Ca s adugm o coloan, altundeva dect la sfrit, ntre descriere i data spre exemplu folosim comanda ALTER TABLE, astfel: ALTER TABLE carti ADD pret MEDIUMINT UNSIGNED AFTER descriere;

INDECI
Cel mai folosit tip de index este id-ul. ID-ul este un numr unic de identificare pentru un element distinct. Avnd structura tabelului carti n forma actual, pentru a alege Romeo si Julieta de William Shakespeare, interogarea ar arta n felul urmtor:
16 1 Lecia

SELECT * FROM carti WHERE autor='William Shakespeare AND titlu=Romeo si Julieta'; Cum procedm, dac avem implementat interogarea n aceast form n aplicaia noastr i ntr-o bun zi primim spre vnzare aceeai carte dar cu un alt pre? Ar trebui s rescriem interogarea pentru a ne adapta situaiei i atunci cutarea unei cri ar fi fcut cu interogarea: SELECT * FROM carti WHERE autor='William Shakespeare' AND titlu=Romeo si Julieta' AND pret= 100000; Dar! dac am folosi un cmp care s conin un numr unic de identificare pentru fiecare carte cutarea ar fi mult simplificat: SELECT * FROM carti WHERE id_carte=15; Un exemplu de id: la un centru de nchiriat casete video, managerul centrului numeroteaz fiecare caset nou achiziionat aezndu-le unele dup altele n ordinea numerotrii, ne interesndu-l unde ar fi locul acestora din punct de vedere alfabetic, mai ales c titluri precum "The Firm" ar putea fi puse i sub litera F i sub litera T, dup cum consider fiecare i atunci confuzia ar fi i mai mare. n plus ca s adauge titluri noi n lista de casete disponibile nu va trebui s rescrie toat lista ci, va aduga doar titlurile noi n ordinea numerotrii. Dumneavoastr putei astfel s aflai rapid ce e nou doar aruncnd o privire pe ultima pagin a ofertei. Atunci cnd cerei o caset dintr-un centru de nchirieri specificai vnztoarei numrul sub care se gsete titlul n list, altfel ei i-ar lua cteva minute bune s caute un film anume din cteva sute. ntr-o tabel id-ul este deosebit de important la fel ca n viaa de zi cu zi; muli au acelai nume dar CNP-ul pentru fiecare, n parte, este unic. S modificm tabelul carti astfel nct fiecare carte s aib un id unic: SET INSERT_ID=#; ALTER TABLE carti ADD id_carte INT UNSIGNED NOT NULL AUTO_INCREXENT FIRST, ADD INDEX (id_carte) ; SET INSERT ID=#; aceast setare este folosit atunci cnd dorim ca fiecare carte deja adugat s aib un id unic. De asemenea, pentru toate crile ce se vor aduga de acum nainte va exista un id unic, incrementat automat. S ne folosim de cele nvate pentru a executa operaii n tabel: INSERT INTO carti(titlu) VALUES ('un text oarecare'); SELECT id_carte, titlu FROM carti; Valoarea id_carte a acestei ultime nregistrri este 9. O folosim pentru a efectua modificri:

17 1

Lecia

UPDATE carti SET titlu='un text nodificat' WHERE id_carte =9; SELECT id_carte, titlu FROM carti WHERE id_carte=9; Rezultatul va fi: id_carte titlu 9 un text modificat

NORMALIZAREA
Normalizarea nseamn structurarea tabelelor bazei de date n aa fel nct datele s ocupe ct mai puin spaiu pe hard-disc, astfel fiind deosebit de util. Chiar dac spaiul nu poate prea o problem, trebuie s luai n considerare posibilitatea de a fi nevoit s v extindei ntr-o zi peste numrul de mega-bii oferit de contractul ncheiat cu SP-ul, din lips de spaiu. De ce s pltii mai mult cnd putei s normalizai? Normalizarea este o practic bun i se recomand a fi luat n calcul ori de cte ori se creaz o baz de date nou. S studiem pentru moment tabelul carti al bazei noastre de date, care n momentul de fa este structurat n felul urmtor. field autor titlu descriere pret data type text text text text text

Ce s-ar ntmpla dac am avea toate crile scrise de un autor anume? Numrul acestora depete 400 i coloana autor ar conine de tot attea ori textul cu numele autorului respectiv. Ce putem face, este s crem un nou tabel pentru autori cu dou cmpuri: id_autor i autor i s nlocuim cmpul autor declarat de tip text, din tabelul cari cu un cmp numit tot id_autor n care pentru toate crile unui autor s punem id-ul din tabelul autori. n acest mod cmpul va conine un numr din cteva cifre n loc de un text mult mai lung. Dac scriem ntr-un document text numele "Popa Ion", se poate observa c acesta ocup 8 bii n timp ce un numr din 3 cifre (presupunnd c id-ul autorului ar fi compus din 3 cifre) ocup doar 3 bii. Astfel, nlocuind elementele repetitive dintr-un tabel cu un id facem o economie serioas de spaiu. S crem, un nou tabel, autori: CREATE TABLE autori ( id_autor SMALLINT UNSIGNED DEFAULT '0' NOT NULL AUTO_INCREMENT, autor TEXT, PRIMARY KEY(id_autor), UNIQUE (id_autor), INDEX (id_autor));

18 1

Lecia

i s redenumim, din tabelul carti, cmpul autor n id_autor. ALTER TABLE carti CHANGE autor id_autor TEXT; Nu i vom modifica deocamdat tipul de date pe care l conine (n cazul nostru TEXT). Ar trebui s revenim ulterior la tabelul autori, s cutm id-ul corespondent fiecrui autor i s modificm manual fiecare cmp n parte. Nu vom face aa, ci vom ncerca s reducem numrul de operaii folosind funcia UPDATE. Adugm nti autorul n noul tabel folosind comanda INSERT dup care aflm id-ul unic repartizat de ctre MySQL folosind comanda SELECT; INSERT INTO autori VALUES('', 'Mihai Eminescu'); SELECT * FROM autori WHERE autor = 'Mihai Eminescu' ; id_autor autor 1 Mihai Eminescu i apoi nlocuim n tabelul carti numele autor-ului cu acest id. UPDATE carti SET id_autor=1 WHERE autor = 'Mihai Eminescu'; Dac mai dorim s inserm alt nregistrare, parcurgem aceeai pai, astfel: INSERT INTO autori VALUES('','George Cosbuc'); SELECT * FROM autori; id_autor autor 1 Mihai Eminescu 2 George Cosbuc UPDATE carti SET id_autor = 2 WHERE autor = 'George Cosbuc' ; Tem: procedai n acelai fel cu fiecare nume de autor din tabelul carti. Acum c avem id_uri numerice n coloana id_autor, s modificm tabelul carti i s transformm tipul cmpului id_autor din TEXT n SMALLINT: ALTER TABLE carti CHANGE id_autor id_autor SMALLINT NOT NULL; Cele dou tabele arat acum astfel: autori id_autor autor 1 2 3 4 Mihai Eminescu George Cosbuc William Shakespeare Alexandru Mitru
19 1 Lecia

carti id_autor titlu 3 1 1 1 4 2 1 Hamlet Poezii Poezii, volumul 2 Poezii, volumul 3 Legendele Olimpului Fire de tort - Poezii Geniu pustiu

Putem "uni" datele din cele dou tabele astfel nct s ne fie afiate numai autor-ul i titlu-l fiecrei nregistrri: SELECT autor, titlu FROM autori, carti WHERE autori.id_autor = carti.id_autor; autor William Shakespeare Mihai Eminescu Mihai Eminescu Mihai Eminescu Alexandru Mitru George Cosbuc Mihai Eminescu titlu Hamlet Poezii Poezii, volumul 2 Poezii, volumul 3 Legendele Olimpului Fire de tort - Poezii Geniu pustiu

Aceast interogare, ia coloana autor din tabelul autori i coloana titlu din tabelul carti i le asociaz dup id_ul autorului care este unic. Dac una din coloanele pe care vrem s le afim are acelai nume n cele dou tabele, o putem apela ca nume_tabel.nume_coloana astfel nct s nu existe ambiguiti, astfel: SELECT autori.id_autor, autori.autor, carti.titlu FROM autori, carti WHERE autori.id_autor=carti.id_autor; n aplicaia noastr va trebui s avem crile ordonate dup domenii deoarce nu dorim s amestecm romanele de rzboi cu manualele colare i cu poeziile. id_autor autor 3 1 1 1 4 2 1 William Shakespeare Mihai Eminescu Mihai Eminescu Mihai Eminescu Alexandru Mitru George Cosbuc Mihai Eminescu
20 1

titlu Hamlet Poezii Poezii, volumul 2 Poezii, volumul 3 Legendele Olimpului Fire de tort - Poezii Geniu pustiu
Lecia

Ne va trebui, n consecin, o nou coloan n tabel, pentru domeniul crii astfel nct, Legendele Olimpului s aparin domeniului Poveti", crile de poezii domeniului Poezii i aa mai departe.

Tem:
modificai tabelul carti pentru a aduga o coloan id_domeniu i creai un nou tabel domenii cu dou cmpuri: id_domeniu i domeniu. Adugai numele de domenii pentru crile din baza de date i id-urile acestora n tabela carti, conform cu id-urile din tabela domenii. afiai titlurile crilor din baza de date i domeniile de care acestea aparin (ca n exemplul de mai sus, cu tabelul autori):

domeniu
Teatru Poezii Poezii Poezii Povesti Poezii

Hamlet Poezii Poezii, volumul 2 Poezii, volumul 3 Legendele Olimpului Fire de tort - Poezii

titlu

Deocamdat avem n baza de date tabelele carti, autori i domenii. n continuare va trebui s mai adugm o tabel de comentarii. Ne reamintim c la fiecare carte vizitatorii notri au posibilitatea s-i poat mprti impresiile. Pentru aceasta vom crea un nou tabel, comentarii, astfel: CREATE TABLE comentarii (id_comentariu INT UNSIGNED DEFAULT '0' NOT NULL AUTO_INCREMENT, id_carte INT UNSIGNED DEFAULT '0', nume_utilizator TEXT, adresa_email TEXT, comentariu TEXT, PRIMARY KEY (id_comentariu), UNIQUE (id_comentariu), INDEX (id_comentariu)); Cmpul id_carte, din acest tabel, ne va folosi pentru a afla toate comentariile aferente unei cri, cu ajutorul interogrii: SELECT * FROM comentarii WHERE id_carte = 1; Pentru urmrirea vnzrilor vom folosi dou tabele, tranzactii i vanzari. S presupunem c Popa Ion cumpr dou cri n data de 1 martie i revine pentru a cumpra nc alte trei cri n 2 martie. n data de 3 martie cnd vin banii pentru prima comand noi vom ti c trebuie s trimitem nite cri lui Popa Ion dar nu tim exact care! Iat de ce, pentru fiecare comand, indiferent de numrul crilor cerute, va trebui s folosim un

21 1

Lecia

numr unic de identificare, numr pe care l inem n tabelul tranzactii alturi de celelalte informaii care ne intereseaz: CREATE TABLE tranzactii (id_tranzactie INT UNSIGNED NOT NULL AUTO_INCREMENT, data_tranzactie TIMESTAMP(10) NOT NULL, nume_cumparator TEXT NOT NULL, adresa_cumparator TEXT NOT NULL, UNIQUE KEY id_tranzactie (id_tranzactie)); Am setat cmpul data_tranzactie ca TIMESTAMP(10) pentru c astfel el va putea fi setat automat de ctre MySQL la fiecare nou nregistrare i va conine data nserrii nregistrrii n format YYYYMMDD. Executai urmtoarele dou interogri: INSERT INTO tranzactii(nume_cumparator, adresa_cumparator) VALUES ('Popa Ion', 'str. Luptei 12, Brasov'); SELECT * FROM tranzactii; Tabelul vanzari va conine informaiile despre crile vndute n fiecare tranzacie: CREATE TABLE vanzari (id_tranzactie INT UNSIGNED NOT NULL DEFAULT '0', nr_buc TINYINT NOT NULL DEFAULT '0'); Cmpul id_tranzactie corespunde celui din tabelul tranzactii iar cmpul id_carte celui din tabelul carti. Cmpul nr_buc ne va fi de folos atunci cnd un utilizator cumpr mai multe exemplare din aceeai carte ntr-o singur tranzacie i de asemenea pentru a putea face o statistic n ceea ce privesc cele mai vndute cri. Introducei cteva nregistrri n tabel folosind id_tranzactie din tabelul tranzactii i mai multe id_carte din tabelul carti: id_tranzactie id_carte bucati_vandute

INSERT INTO vanzari VALUES (1, 2, 1) ; INSERT INTO vanzari VALUES (1, 3, 1) ; INSERT INTO vanzari VALUES (1, 4, 30) ; n tranzacia cu id_tranzacie egal cu 1, s-au vndut: 1 bucati_vandute acolo unde id_carte este 2, 1 bucati_vandute acolo unde id_carte este 3 i 30 bucati_vandute acolo unde id_carte este 4.

22 1

Lecia

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