Sunteți pe pagina 1din 32

100 Partea l Utilizarea general a sistemului MySQL

Categoriile generale de valori pe care le poate reprezenta MySQL, inclusiv valoarea NULL.
Tipurile concrete de date pe care le furnizeaz MySQL pentru coloanele tabelelor, precum i proprietile care
caracterizeaz fiecare tip de coloan. Unele dintre tipurile de coloane MySQL au un caracter destul de general,
cum este tipul sir CHAR. Alte tipuri, cum este TIMESTAMP, au comportri speciale, pe care trebuie s le
nelegei pentru a evita surprizele.
Alegerea adecvat a tipului de coloan pentru tabelele dumneavoastr. Este important s tii modul de a alege
tipul cel mai adecvat intereselor dumneavoastr cnd construii un tabel, precum i s alegei ntre un tip i altul
atunci cnd se pot aplica mai multe tipuri pentru categoria de valori pe care dorii s o stocai.
Regulile MySQL pentru evaluarea expresiilor. MySQL ofer o gam larg de operatori i funcii pe care le
putei folosi pentru a regsi, afia i manipula date. Regulile pentru evaluarea expresiilor includ regulile care
controleaz conversiile de tip, atunci cnd o valoare de un tip este folosit ntr-un context care impune o valoare
de un alt tip.
Este important s nelegei cnd se produce i cum funcioneaz conversia de tip; unele conversii nu au nici un
sens si genereaz valori fr nici o semnificaie. Prin repartizarea irului "13" ntr-o coloan ntreag se obine
valoarea 13, dar repartizarea irului "abc" n coloana respectiv are ca rezultat valoarea O, deoarece "abc" nu
arat ca un numr. Mai ru, dac efectuai o comparaie fr a cunoate regulile de conversie putei provoca
pagube serioase, cum ar fi actualizarea sau tergerea tuturor rndurilor dintr-un tabel atunci cnd intenionai s
modificai numai cteva rnduri.
Dou anexe conin informaii suplimentare despre tipurile de coloane, operatorii i funciile MySQL. Acestea
sunt Anexa B, Referin de tipuri de coloane", respectiv Anexa C, Referin de operatori i funcii".
Tipuri de date MySQL
MySQL cunoate" numeroase tipuri de date, n spe categorii generale n care pot fi reprezentate diverse valori.
Valori numerice
Numerele sunt valori precum 48 sau 193.62. MySQL nelege numere specificate ca ntregi (fr parte
fracionar) sau valori cu virgul mobil (cu parte fracionar). ntregii pot fi specificai n format zecimal sau
hexazecimal.
Un ntreg const dintr-o secven de cifre. Un ntreg specificat n form hexazecimal const din secvena Ox
urmat de una sau mai multe cifre hexazecimale (cuprinse ntre 0-9, respectiv a-f). De exemplu, OxOa este 10 n
format zecimal, iar Oxf f f f este 65535 n format zecimal. Cifrele hexazecimale non-numerice pot fi specificate
cu majuscule sau minuscule, dar secvena de nceput Ox nu poate fi scris sub forma OX. Cu alte cuvinte, OxOa
si OxOA sunt corecte, dar OXOa i OXOA nu sunt.
Un numr cu virgul mobil const dintr-o secven de cifre, o virgul de separare a prii fracionare i o alt
secven de cifre. Una dintre cele dou secvene de cifre poate fi vid, dar nu ambele simultan.
Capitolul 2 Lucrul cu date n MySQL i SQL 101
MySQL nelege notaia tiinific. Aceasta este indicat prin inseria imediat dup un numr ntreg sau n virgul
mobil a literei e sau E, unui caracter semn (+ sau -) i unui exponent ntreg. 1.34E+12 i 43.27e-1 reprezint
numere scrise n notaie tiinific corect. Pe de alt parte, 1.34E12 nu este scris corect, deoarece lipsete
caracterul semn naintea exponentului. Numerele hexazecimale nu pot fi folosite n notaiile tiinifice; caracterul
e care se afl la nceputul exponentului este, de asemenea, o cifr hexazecimal corect i astfel se pot crea
confuzii.
Numerele pot fi precedate de un semn minus (-) pentru a semnala o valoare negativ.
Valori ir (caracter)
irurile sunt valori ca "Bucureti, Romnia" sau "pacientul se simte mai bine". Pentru a delimita o valoare ir se
pot folosi ghilimele simple sau duble.
n interiorul irurilor se pot folosi numeroase secvene escape, care se pot folosi pentru a preciza caractere
speciale, aa cum se poate vedea n tabelul 2.1. Fiecare secven ncepe cu un caracter backslash (\) pentru a
semnifica o excepie temporar de la regulile obinuite de interpretare a caracterelor. Reinei c un octet NUL nu
este unul i acelai lucru cu o valoare NULL; NUL este un octet de valoare zero, n timp ce NULL semnific
absena unei valori.
Tabelul 2.1 Secvene escape din iruri
Secven Semnificaie

\o NUL (ASCII 0)
v Ghilimele simple
\" Ghilimele duble
\b tergere caracter anterior
\n Caracter linie nou
\r Retur de car
\t Caracter de tabulare
\\ Backslash
Pentru a include ghilimele ntr-un ir, putei proceda astfel:
Dublai ghilimelele, dac irul este inclus ntre ghilimele folosind acelai caracter:
'Anii "701
"El zise: ""Ti-am spus eul"""
ncadrai irul folosind celelalte ghilimele; n acest caz, nu dublai ghilimelele din ir:
"Anii '70"
'El zise: "Ti-am spus eul"'
Anulai semnificaia ghilimelelor cu un caracter backslash; aceast metod este aplicabil indiferent de tipul
ghilimelelor folosite pentru a ncadra irul;
'Anii \'70' 'Anii \'70"
102 Partea l Utilizarea general a sistemului MySQL
"El zise: \"Ti-am spus eul\""
'El zise: \"Ti-am spus eu!\"'
n contextele irurilor, se pot folosi constantele hexazecimale pentru a specifica valorile de tip ir. Sintaxa este
cea descris anterior pentru valorile numerice, dar perechile de cifre hexazecimale sunt interpretate drept coduri
ASCII si sunt convenite n caractere. Rezultatul este folosit sub form de ir. De exemplu, cnd este interpretat
sub form de ir, 0x616263 este "abc".
Valori de tip dat si or (temporale)
Datele si orele sunt valori precum " 1999 - 06 -17" sau " 12:30:43". De asemenea, MySQL nelege valorile
dat/or combinate, precum "1999-06-17 12:30:43". Reinei faptul c MySQL reprezint datele n ordinea an-
lun-zi. Acest lucru i surprinde deseori pe nceptorii n materie de MySQL, dei acest format este standardul
SQL ANSI. Putei afia valorile datelor n orice mod dorii folosind funcia DATE_FORMAT(), dar formatul de
afiare prestabilit afieaz mai nti anul, iar valorile de intrare trebuie specificate ncepnd cu anul.
Valoarea NULL
NULL este un fel de valoare fr tip", n general, este folosit cu semnificaia fr valoare", valoare
necunoscut", valoare lips", n afara domeniului", nici una din precedentele opiuni" i aa mai departe.
Putei insera valori NULL n tabele, le putei regsi din tabele i putei testa dac o valoare este sau nu NULL.
Nu putei efectua operaii aritmetice cu valori NULL. (Dac ncercai, rezultatul este NULL.)
Tipuri de coloane MySQL
Fiecare tabel dintr-o baz de date este alctuit dintr-una sau mai multe coloane. Cnd creai un tabel folosind o
instruciune CREATE TABLE, specificai un tip pentru fiecare coloan. Un tip de coloan este mai specific dect
un tip de date, care este numai o categorie general de genul numr" sau ir". Un tip de coloan caracterizeaz
cu exactitate categoria de valori pe care o poate conine o coloan a unui tabel dat, cum este SMALLINT sau
VARCHAR(32).
Tipurile de coloane MySQL reprezint mijloacele prin care descriei categoriile de valori pe care le conin
coloanele unui tabel, care, la rndul lor, determin modul n care MySQL trateaz aceste valori. De exemplu,
dac avei valori numerice, le putei stoca folosind un tip de coloan numeric sau ir, dar MySQL va trata
valorile oarecum diferit, n funcie de modul n care le stocai. Fiecare tip de coloan are numeroase
caracteristici:
Ce tip de valori putei stoca n coloana respectiv
Spaiul pe care l ocup valorile, precum i dac valorile sunt de lungime fix (toate valorile de acel tip ocup
aceeai cantitate de spaiu) sau de lungime variabil (cantitatea de spaiu depinde de valoarea particular stocat)
Modul de comparare si stocare a valorilor din tipul respectiv
Capitolul 2 Lucrul cu date n MySQL i SQL 103
Dac tipul respectiv accept sau nu valori NULL
Dac tipul respectiv poate fi indexat sau nu
Vom examina succint tipurile de coloan MySQL pentru a avea o imagine de ansamblu, dup care vom discuta
mai detaliat proprietile care caracterizeaz fiecare tip.
O examinare a tipurilor de coloane
MySQL furnizeaz tipuri de coloane pentru valori din toate categoriile generale de tipuri de date, cu excepia
valorii NULL. Valoarea NULL acoper toate tipurile, n sensul c posibilitatea unei coloane de a conine sau nu
valori NULL este tratat ca atribut de tip. MySQL are tipuri de coloane att pentru valorile ntregi, ct i pentru
cele cu virgul mobil, aa cum se poate vedea n tabelul 2.2. Coloanele ntregi pot fi cu sau fr semn. Un
atribut special permite valorilor din coloanele ntregi s fie generate automat, ceea ce este util n aplicaii care
impun numere dintr-o secven sau de identificare unice.
Tabelul 2.2 Tipuri de coloane numerice
Numele tipului
TINYINT
SMALLINT
MEDIUMINT
INT
BIGINT
FLOAT
DOUBLE
DECIMAL
Semnificaie
Un ntreg foarte mic
Un ntreg mic
Un ntreg de dimensiune medie
Un ntreg standard
Un ntreg mare
Un numr cu virgul mobil n precizie simpl
Un numr cu virgul mobil n dubl precizie
Un numr cu virgul mobil, reprezentat sub form de ir
Tipurile de coloane ir din MySQL sunt prezentate n tabelul 2.3. irurile pot conine orice, chiar si date binare
arbitrare, cum sunt imaginile sau sunetele. irurile pot fi comparate n funcie de sensibilitatea lor la diferena
ntre majuscule i minuscule. De asemenea, putei efectua cu iruri stabilirea de corespondene cu un model. (De
fapt, n MySQL putei efectua stabilirea de corespondene cu un model pentru orice tip de coloane, dar aceast
operaie se execut cel mai frecvent cu tipuri ir.)
Tabelul 2.3 Tipuri de coloane ir _________________
Numele tipului
CHAR
VARCHAR
TINYBLOB
BLOB
MEDIUMBLOB
Semnificaie
Un ir de caractere de lungime fix Un ir de caractere de lungime variabil Un BLOB (obiect binar mare) foarte
mic Un BLOB mic Un BLOB de dimensiuni medii
Continuare
104 Partea l Utilizarea general a sistemului MySQL Tabelul 2.3 Continuare
Numele tipului
LONGBLOB
TINYTEXT
TEXT
MEDIUMTEXT
LONGTEXT
ENUM
SET
Semnificaie
Un BLOB de dimensiuni mari
Un ir text foarte mic
Un ir text mic
Un ir text de dimensiuni medii
Un ir text de mari dimensiuni
O enumerare; coloanelor li se poate atribui un membru al enumerrii
Un set; coloanelor li se pot atribui mai muli membri ai unui set
Tipurile date i or din MySQL sunt prezentate n tabelul 2.4. Pentru valori temporale, MySQL furnizeaz tipuri
pentru date (cu sau fr or), ore i amprente de timp (un tip special, care v permite s detectai data i ora
efecturii ultimei modificri ntr-o nregistrare). De asemenea, exist un tip pentru reprezentarea eficient a
valorilor anilor, atunci cnd nu avei nevoie de o dat complet.
Tabelul 2.4 Tipuri de coloane dat i or
Numele tipului Semnificaie
DATE O valoare pentru dat, n format "AAAA-LL -22'
TIME O valoare pentru or, n format 'hh:mm:ss'
DATETIME O valoare pentru dat si or, n format 'AAAA-LL -ZZ hh :mm:ss'
TIMESTAMP O valoare pentru amprenta de timp, n format AAAALLZZhhmmss
YEAR O valoare pentru an, n format AAAA
Pentru a crea un tabel, emitei o instruciune CREATE TABLE i specificai o list a coloanelor care alctuiesc
tabelul. Fiecare coloan are un nume i un tip, iar la fiecare tip se pot asocia mai multe atribute. Iat un exemplu
care creeaz un tabel denumit tabeluljneu, cu trei coloane, denumite f, c i i: CREATE TABLE tabeluljneu
f FLOAT(10,4),
C CHAR(15) NOT NULL DEFAULT "nimic",
i TINYINT UNSIGNED NULL
Sintaxa pentru declararea unei coloane este urmtoarea:
nume_col tip_col [atribute_coloana] [atribute_generale] Numele coloanei este dat de nume_col. Numele
coloanelor pot avea o lungime de maxi- "J mum 64 de caractere i pot fi alctuite din caractere alfanumerice,
precum si din carac-1 terul de subliniere i simbolul dolarului (n spe _ i $). Un nume de coloan poate J
ncepe cu orice caracter admis ntr-un nume, inclusiv cu o cifr. Totui, urt nume fltrjl poate fi compus integral
din cifre, deoarece astfel ar deveni practic confundabil cu unii
Capitolul 2 Lucrul cu date n MySQL i SQL 105
numr. Cuvinte precum SELECT, DELETE sau CREATE sunt rezervate i nu pot fi folosite drept nume de
coloan. Totui, numele funciilor (cuvinte precum POS i MI N) nu sunt rezervate si pot fi folosite.
Tipul de coloan tip_col precizeaz categoria exact de valori pe care le poate conine coloana. Specificatorul de
tip mai poate indica i lungimea maxim a valorilor pe care le stocai n coloan. Pentru unele tipuri, specificai
lungimea n mod explicit sub form numeric. Pentru altele, lungimea se deduce din numele tipului. De
exemplu, CHAR (10) specific o lungime explicit de 10 caractere, n timp ce valorile TINYBLOB au o lungime
maxim implicit de 255 caractere. Unii dintre specificatorii de tip v permit s indicai o lime maxim afiat
(numrul de caractere de utilizat pentru afiarea valorilor). Tipurile de coloane cu virgul mobil permit
specificarea numrului de cifre dup virgul, astfel nct s putei controla nivelul de precizie al valorilor.
Dup tipul coloanei, putei specifica atribute opionale specifice unui anumit tip, precum si atribute de ordin mai
general. Atributele funcioneaz ca modificatori de tip. Acestea determin programul MySQL s modifice ntr-un
fel sau altul tratamentul aplicat valorilor din coloan:
Atributele permise specifice tipului depind de tipul de coloan pe care l alegei. De exemplu, UNSIGNED este
permis numai pentru tipurile ntregi, iar BINARY este permis numai pentru tipurile CHAR si VARCHAR.
Atributele generale pot fi date pentru orice tip de coloan, cu anumite excepii. Putei specifica NULL sau NOT
NULL pentru a preciza dac o coloan poate conine sau nu valori NULL. De asemenea, putei specifica
DEFAULT valoare_prestabilita pentru a arta c o coloan trebuie s primeasc valoarea valoare_prestabilita
atunci cnd este creat un rnd nou fr a se specifica n mod explicit valoarea coloanei. Valoarea
valoare_prestabilita trebuie s fie o constant; nu poate fi o expresie i nici nu poate face referire la alte coloane.
Nu putei specifica o valoare prestabilit pentru coloanele BLOB sau TEXT.
Dac sunt precizate mai multe atribute specifice unei anumite coloane, acestea pot fi precizate n orice ordine, cu
condiia ca acestea s respecte tipul coloanei i s precead toate atributele generale. Similar, dac sunt date mai
multe atribute generale, ele pot fi specificate n orice ordine, cu condiia s respecte tipul coloanei i s fie
plasate dup toate atributele specifice de coloan existente.
n continuare, aceast seciune discut despre fiecare dintre tipurile de coloan MySQL, pentru a prezenta sintaxa
utilizat la declararea tipului i proprietile care o caracterizeaz, cum ar fi cerinele privind domeniul i
capacitatea de stocare. Specificaiile de tip sunt prezentate aa cum sunt utilizate acestea n instruciunile
CREATE TABLE. Informaiile opionale sunt ncadrate ntre paranteze drepte ([ ]). De exemplu, sintaxa
MEDIUMINT[ (M) ] arat c limea maxim de afiare, specificat sub forma (M), este opional. Pe de alt
parte, pentru CHAR (M), lipsa parantezelor arat c (M) este obligatorie.

106 Partea l Utilizarea general a sistemului MySQL


Tipuri de coloane numerice
Tipurile de coloane numerice din MySQL se ncadreaz n dou categorii generale:
Tipuri ntregi. Pentru numerele fr parte fracionar, precum 1, 43, -3,0 sau -796432. Putei folosi coloanele
ntregi pentru date reprezentate de numere ntregi, precum greutatea aproximat la cea mai apropiat cantitate n
kilograme, nlimea aproximat la valoarea n centimetri cea mai apropiat, numrul de stele dintr-o galaxie,
numrul de persoane dintr-o gospodrie sau numrul de bacterii dintr-un vas de cultur.
Tipuri cu virgul mobil. Pentru numere care pot avea o parte fracionar, precum 3.14159, -. 00273, -4.78 sau
39. 3E+4. Putei folosi tipuri de coloane cu virgul mobil pentru valori care pot avea o parte fracionar sau care
sunt extrem de mari sau de mici. Printre tipurile de date care pot fi reprezentate sub form de valori cu virgul
mobil sunt: producia agricol medie, distanele, valorile monetare (preul unui articol sau un salariu), rata
omajului sau preurile aciunilor la burs. Acestea sunt tratate sub form de valori cu virgul mobil cu o parte
fracionar zero.
Numele i domeniul fiecrui tip numeric sunt prezentate n tabelul 2.5. Cantitatea de spaiu necesar pentru
valorile de fiecare tip este prezentat n tabelul 2.6.
Instruciunea CREATE TABLE
Exemplele folosite n acest capitol utilizeaz in extenso instruciunea CREATE TABLE. Instruciunea ar trebui
s v fie destul de cunoscut, deoarece am folosit-o n seciunea de manual a capitolului 1, Introducere n
MySQL i SQL". De asemenea, vezi informaiile despre instruciunea CREATE TABLE din Anexa D, Referin
de sintax SQL".
Tabelul 2.5 Domenii de existen ale tipurilor de coloane numerice Specificaie de tip
TINYINT[(W)]
SMALLINT[(M)] MEDIUMINT[(M)] INT[(M)] BIGINT[(M)]
FLOAT[(W,0)], FLOAT(4) DOUBLE[(M,D)], FLOAT(8) DECIMAL(M,D)
Domeniu
Valori cu semn: ntre -128 i 127 (ntre -27 i 27-1) Valori fr semn ntre O i 255 (ntre O i 28-1)
Valori cu semn: ntre-32768 i 32767 (ntre-215 i 215-1) Valori fr semn: ntre O i 65535 (ntre O i 216-1)
Valori cu semn: ntre -8388608 i 8388607 (ntre -223 i 223-1) Valori fr semn: ntre O i 16777215 (ntre O i
224-1)
Valori cu semn: ntre - 2147483648 i 2147483647 (ntre -231 i 231-1> Valori fr semn: ntre O i 4294967295
(ntre O i 232-1)
Valori cu semn: ntre -9223372036854775808 i
9223372036854775807 (ntre-263 i 2^-1),
Valori fr semn: ntre O i 18446744073709551615 (ntre O i 64-!)
Valori minime diferite de zero: 1.175494351E-38 Valori maxime diferite de zero: 3.402823466E+38
Valori minime diferite de zero: 2.2250738585072014E-308 Valori maxime diferite de zero:
1.7976931348623157E+308
Variaz; domeniul depinde de u i D.
Capitolul 2 Lucrul cu date n MySQL i SQL 107 Tabelul 2.6 Necesiti de spaiu de stocare pentru tipurile
de coloane numerice
Specificaie de tip
TINYINT[(M)]
SMALLINT[(M)]
MEDIUMINT[(M)]
INT[(M)]
BIGINT[(M)]
FLOAT[(M,0)], FLOAT(4)
DOUBLE[(M,D)], FLOAT(8)
DECIMAL(,D)
Spaiu necesar
1 octet
2 octei
3 octei
4 octei 8 octei 4 octei 8 octei
M octei (versiune MySQL anterioar versiunii 3.23), M+2 octei (versiune MySQL ulterioar versiunii 3.23 sau
chiar versiunea 3.23)
MySQL furnizeaz cinci tipuri ntregi: TINYINT, SMALLINT, MEDIUMINT, INT i BIGIN. INTEGER este
un sinonim pentru INT. Aceste tipuri variaz din punctul de vedere al domeniului de valori pe care l pot
reprezenta. Coloanele ntregi pot fi declarate ca UNSIGNED pentru a interzice valorile negative; astfel,
domeniul pentru coloan este deplasat n sus pe axa numerelor, ncepnd astfel de la 0. De asemenea, tipurile
variaz din punct de vedere al cantitii de spaiu necesare. Tipurile cu un domeniu mai extins necesit un spaiu
de stocare mai mare.
MySQL furnizeaz trei tipuri cu virgul mobil: FLOAT, DOUBLE i DECIMAL. Spre deosebire de tipurile
ntregi, tipurile cu virgul mobil nu pot fi UNSIGNED, iar domeniul lor este diferit de acela al tipurilor ntregi,
prin aceea c tipul respectiv nu poate reprezenta numai o valoare maxim, ci i o valoare minim diferit de zero.
Valorile minime furnizeaz o msur a preciziei tipului, ceea ce este deseori important pentru nregistrarea
datelor tiinifice. (Exist, desigur, valori maxime i minime negative corespunztoare.)
DOUBLE PRECISION! (M,O)] i REAL[(M,D)] sunt sinonime pentru DOUBLE[ (M,D) ]. NUMERIC(,D)este
sinonim cu DECIMAL(M,D). FLOAT(4) i FLOAT(8) sunt furnizate pentru compatibilitatea cu ODBC. nainte
de MySQL 3.23, acestea erau sinonime cu FLOAT(10,2), respectiv DOUBLE (16,4). ncepnd de la MySQL
3.23, FLOAT (4) i FLOAT (8) i au propriul comportament, descris pe scurt n continuare.
Cnd alegei un tip numeric, v gndii la domeniul de valori pe care trebuie s-1 reprezentai i alegei cel mai
mic tip care va acoperi domeniul. Prin alegerea unui tip mai mare se pierde spaiu, rezultnd astfel tabele inutil
de mari, care nu pot fi prelucrate la fel de eficient ca si atunci cnd ai fi ales un tip mai mic. Pentru valori
ntregi, TINYINT este optim dac domeniul de valori al datelor dumneavoastr este redus, cum ar fi vrsta unei
persoane sau numrul de frai sau surori. MEDIUMINT poate reprezenta milioane de valori si poate fi folosit
pentru mult mai multe tipuri de valori, cu preul unui spaiu de stocare ceva mai mare. BIGIN are cel mai mare
domeniu dintre toate tipurile, dar necesit un spaiu de stocare dublu fa de cel mai mic tip ntreg urmtor (lNT)
i trebuie s fie folosit numai atunci cnd este ntr-adevr nevoie. Pentru valori cu virgul mobil, DOUBLE
ocup de dou ori mai mult spaiu dect FLOAT. Cu excepia situaiilor cnd avei nevoie de o precizie
excepional sau de un domeniu de valori extrem de mare, probabil c v putei reprezenta datele la numai
jumtate din spaiul de stocare, folosind FLOAT.

108 Partea l Utilizarea general a sistemului MySQL


Cnd declarai o coloan de tip ntreg, putei specifica o dimensiune opional de afiare M. Dac este dat, M
trebuie s fie un ntreg cuprins ntre 1 i 255 i reprezint numrul de caractere folosit pentru a afia valorile din
coloan. De exemplu, MEDIUMINT(4) specific o coloan MEDIUMINT cu o lime de afiare egal cu 4.
Dac declarai o coloan de tip ntreg fr o lime explicit, este atribuit o lime prestabilit. Valorile
prestabilite constituie lungimile valorilor celor mai lungi" pentru fiecare tip. Dac reprezentarea care se poate
afia a unei anumite valori necesit mai mult de M caractere, atunci se va afia valoarea total; valorile nu vor fi
amputate" pentru a se ncadra n limita celor M caractere.
Pentru fiecare tip de coloan cu virgul mobil, putei specifica o dimensiune maxim de afiare M i numrul de
cifre dup virgul D. Valoarea lui M trebuie s fie cuprins ntre l si 255. Valoarea lui D poate fi cuprins ntre O
i 30, dar nu trebuie s depeasc M-2. (Dac suntei un cunosctor al terminologiei ODBC, M i D corespund
conceptelor ODBC de precizie" i scar".) M i D sunt opionale pentru FLOAT i DOUBLE, dar sunt
obligatorii pentru DECIMAL.
Acolo unde M i D sunt opionale, n caz de omisiune sunt folosite valori prestabilite. Urmtoarea instruciune
creeaz un tabel pentru a ilustra valorile prestabilite ale opiunilor M i D pentru tipurile de coloane numerice
(DECIMAL nu este inclus, deoarece M i D nu sunt opionale pentru tipul respectiv): CREATE TABLE
tabeluljneu
itiny TINYINT, itiny_u TINYINT UNSIGNED, ismall SMALLINT, ismall_u SMALLINT UNSIGNED,
imedium MEDIUMINT, imedium_u MEDIUMINT UNSIGNED, ireg INT, ireg_u INT UNSIGNED, ibig
BIGINT, ibig_u BIGINT UNSIGNED, fp_single FLOAT, fp_double DOUBLE
Dac emitei o instruciune DESCRIBE tabelul_meu dup crearea tabelului, coloanele Field si Type ale
datelor de ieire se vor prezenta astfel2:
Field Type
itiny tinyint(4)
itiny_u tinyint(3) unsigned
ismall smallint(6)
ismall_u smallint(S) unsigned
imedium mediumint(9)
imediumjj mediumint(8) unsigned
ireg int(11)
ireg u int(IO) unsigned
ibig bigint(20)
ibig_u bigint(20) unsigned
fp_single float(10,2)
fp_double float(16,4)
2 Limea de afiare pentru BIGINT va fi 21 (nu 20) dac rulai aceast interogare folosind o versiuni j MySQL
anterioar versiunii 3.23, datorit unei erori minore. - N.A.
Capitolul 2 Lucrul cu date n MySQL i SQL 109
Fiecare coloan numeric are un domeniu de valori determinat de tipul coloanei. Dac ncercai s inserai o
valoare care se afl n afara domeniului coloanei, se produce o trunchiere: MySQL taie" valoarea corespunztor
punctului final adecvat al domeniului i folosete rezultatul. La regsirea valorilor nu se produce nici o
trunchiere.
Trunchierea valorilor se produce n conformitate cu domeniul tipului coloanei, nu cu limea de afiare. De
exemplu, o coloan SMALLINT(3) are o lime de afiare egal cu 3 i un domeniu cuprins ntre -32768 si
32767. Valoarea 12345 este mai lat" dect limea de afiare, dar se afl n interiorul domeniului coloanei, deci
este inserat fr tiere" si regsit sub forma 12345. Valoarea 99999 se afl n afara domeniului, deci este
redus la 32767 cnd este inserat. La regsirile ulterioare, valoarea apare sub forma 32767.
n general, valorile atribuite unei coloane cu virgul mobil sunt rotunjite la numrul de zecimale indicat la
specificarea coloanei. Dac stocai valoarea 1.234563 ntr-o coloan FLOAT (8,1), rezultatul este 1.2. Dac
stocai aceeai valoare ntr-o coloan FLOAT (8,4), rezultatul este 1.2346. Aceasta nseamn c trebuie s
declarai coloanele cu virgul mobil cu un numr de zecimale suficient de mare pentru a v oferi valori la
precizia dorit. Dac avei nevoie de o precizie de ordinul miimilor, nu declarai un tip cu numai dou cifre dup
virgul.
Excepia de la acest mod de manipulare a valorilor cu virgul mobil const n aceea c, n MySQL 3.23,
comportarea tipurilor FLOAT(4) si FLOAT(8) s-a modificat. Aceste dou tipuri sunt acum de tip precizie simpl
(4 octei), respectiv dubl (8 octei), care sunt tipuri cu virgul mobil autentice, n sensul c valorile sunt stocate
aa cum sunt date, n cadrul limitelor impuse de componentele dumneavoastr hardware.
Tipul DECIMAL este diferit de FLOAT i DOUBLE, n sensul c valorile DECIMAL sunt, de fapt, stocate sub
form de iruri. Domeniul maxim posibil pentru DECIMAL este acelai ca pentru DOUBLE, dar domeniul
efectiv este determinat de valorile parametrilor M i D. Dac M variaz i D rmne fix, domeniul crete dac M
crete. Acest fapt este ilustrat de primele trei rnduri ale tabelului 2.7. Dac M rmne fix i D variaz, domeniul
devine mai mic dac D creste, dei precizia creste. Acest fapt este ilustrat de ultimele trei rnduri ale tabelului
2.7.
Tabelul 2.7 Influena valorilor parametrilor M si D asupra domeniului tipului DECIMAL (M,D)
Specificaie de tip
DECIMAL(4,1) DECIMAL(5,1) DECIMAL(6,1) DECIMAL(6,2) DECIMAL(6,3)
Domeniu (pentru MySQL < 3.23)
ntre -9,9 i 99,9 ntre -99,9 i 999,9 ntre -999,9 i 9999,9 ntre -99,99 i 999,99 ntre -9,999 i 99,999
Domeniu (pentru MySQL 3.23)
ntre -999,9 i 9999,9 ntre -9999,9 i 99999,9 ntre -99999,9 i 999999,9 ntre -9999,99 i 99999,99 ntre
-999,999 i 9999,999
Domeniul unui tip DECIMAL dat depinde de versiunea dumneavoastr de MySQL. Pentru versiunile MySQL
anterioare versiunii 3.23, coloanele de tip DECIMAL (M, D) sunt stocate folosind M octei per valoare, iar
caracterul semn (dac este necesar) i virgula sunt incluse n cei M octei. Astfel, pentru un tip DECIMAL(5,2),
domeniul este cuprins ntre -9,99 si 99,99, deoarece n acest interval se ncadreaz toate valorile de 5 caractere
posibile.
f 4. T^P-K '
I- , JB^H ,
-iSP
' n limba englez, virgula zecimal se reprezint ca punct zecimal. MySQL folosete acest sistem. - N.T
110 Partea l Utilizarea general a sistemului MySQL
ncepnd de la MySQL 3.23, valorile DECIMAL sunt manipulate n conformitate cu specificaia ANSI, care
precizeaz c un tip DECI MAL (M, D) trebuie s poat reprezenta toate valorile cu M cifre i D cifre dup
virgul. De exemplu, DECIMAL(5,2) trebuie s poat reprezenta valori cuprinse ntre -999,99 i 999,99.
Caracterul semn si virgula trebuie si ele stocate, deci valorile DECIMAL ncepnd de la versiunea MySQL 3.23
folosesc M+2 octei. Pentru DECIMAL(5,2) sunt necesari 7 octei pentru cea mai lung" valoare (-999,99). La
extremitatea pozitiv a domeniului, octetul de semn nu este necesar pentru memorarea unui caracter semn, deci
MySQL l folosete pentru a extinde domeniul dincolo de cel cerut prin specificaia ANSI. Pentru
DECIMAL(5,2), valoarea maxim poate fi 9999,99, deoarece sunt disponibili 7 octei.
Pe scurt, domeniul tipului DECIMAL(M,D) pentru versiunile de la MySQL 3.23 n sus" este echivalent cu
domeniul tipului DECIMAL(M+2,D) din versiunile anterioare.
n toate versiunile de MySQL, dac D este egal cu O pentru o coloan DECIMAL, virgula nu este stocat.
Efectul este o extindere a domeniului coloanei cu un ordin de mrime suplimentar, deoarece octetul folosit n
mod normal pentru stocarea virgulei se poate utiliza pentru o alt cifr.
Atributele tipului de coloan numeric
Atributul ZEROFILL poate fi specificat pentru toate tipurile numerice. Acesta determin completarea cu zerouri
iniiale a valorilor afiate pentru coloan, pentru a se obine limea de afiare. Putei folosi ZEROFILL cnd
dorii s v asigurai c valorile din coloane sunt ntotdeauna afiate folosind un numr de cifre dat. De fapt, este
mai bine s spunem un numr minim dat de cifre", deoarece valorile cu un numr de cifre mai mare dect
limea de afiare sunt afiate complet, fr a fi tiate". Putei vedea acest lucru emind urmtoarele
instruciuni:
CREATE TABLE tabeluljneu (completare_zerouri INT(5) ZEROFILL) INSERT INTO tabeluljneu
VALUES(1),(100),(10000),(1000000) SELECT completare_zerouri FROM tabeluljneu
Datele de ieire ale instruciunii SELECT sunt prezentate n continuare. Observai c valoarea final, care are un
numr de cifre mai mare dect limea de afiare a coloanei, este afiat complet:
completare_zerouri
00001
00100
10000
1000000
Alte dou atribute pot fi specificate numai pentru tipurile de coloane ntregi:
AUTO_INCREMENT. Folosii atributul AUTO_INCREMENT cnd dorii s generai identifi-,; catori unici
sau valori n serie, n mod normal, valorile AUTO_INCREMENT ncep de la V i cresc cu o unitate pentru
fiecare rnd. Cnd inserai NULL ntr-o coloana;j AUTO_INCREMENT, MySQL insereaz o valoare cu o
unitate mai mare dect valoare|| maxim curent din acea coloan, ntr-un tabel putei avea maximum o coloanj
AUTO INCREMENT.
Capitolul 2 Lucrul cu date n MySQL i SQL 111
Pentru orice coloan unde dorii s folosii AUTO_INCREMENT, coloana trebuie s fie declarat NOT NULL
i, de asemenea, ca PRIMARY KEY sau drept cheie UNIQUE. De exemplu, putei declara o asemenea coloan
n oricare din urmtoarele moduri: CREATE TABLE ai (i INT AUTO_INCREMENT NOT NULL PRIMARY
KEY) CREATE TABLE ai (i INT AUTO_INCREMENT NOT NULL, PRIMARY KEY (i)) CREATE
TABLE ai (i INT AUTO_INCREMENT NOT NULL, UNIQUE(i)) Comportarea atributului
AUTO_INCREMENT este discutat mai aprofundat n paragraful Lucrul cu secvene".
UNSIGNED. Acest atribut interzice valorile negative. Dac o coloan primete atributul UNSIGNED,
dimensiunea domeniului tipului de date de baz nu se modific, ci pur i simplu este deplasat nainte (spre
dreapta) pe axa numerelor. Gndii-v la aceast specificaie de tabel: .
CREATE TABLE tabeluljneu
(
itiny TINYINT,
itiny_u TINYINT UNSIGNED
)
itiny si itinyjj sunt ambele coloane de tip TINYINT, cu un domeniu de 256 de valori, dar domeniul lui itiny este
cuprins ntre -128 si 127, n timp ce domeniul lui itiny_u este cuprins ntre O i 255.
UNSIGNED este util pentru coloane n care intenionai s stocai date care nu iau valori negative, cum sunt
valorile populaiilor sau cifrele privind prezena la un curs. Dac folosii o coloan obinuit, cu semn, pentru
asemenea valori, folosii numai jumtate din domeniul tipului de coloan. Cnd coloana primete atributul
UNSIGNED, efectiv i dubleaz domeniul. Dac folosii coloana pentru numere n secven, vei avea nevoie de
un numr dublu de valori pentru a epuiza domeniul dac declarai coloana cu atributul UNSIGNED.
Dup atributele pe care tocmai le-am descris, care sunt caracteristice coloanelor numerice, mai putei specifica si
atributele generale NULL i NOT NULL. Dac nu specificai NULL sau NOT NULL, valoarea prestabilit este
NULL. De asemenea, putei specifica o valoare prestabilit folosind atributul DEFAULT. Dac nu specificai o
valoare prestabilit, aceasta va fi aleas automat. Pentru toate tipurile de coloane numerice, valoarea prestabilit
este NULL pentru coloanele care pot conine NULL, respectiv O pentru celelalte.
Exemplul urmtor creeaz un tabel cu trei coloane I NT, cu valorile prestabilite -l, l i NULL:
CREATE TABLE t
(
11 INT DEFAULT -1,
12 INT DEFAULT 1,
13 INT DEFAULT NULL
'+"
t1. .
V&&,.
112 Partea l Utilizarea general a sistemului MySQL
Lucrul cu secvene
Multe aplicaii trebuie s foloseasc numere unice pentru motive legate de identificare. Necesitatea unicitii
valorilor survine ntr-un numr de contexte: numere de membri, numerotarea mostrelor sau a loturilor,
identificatori de clieni, etichete ale rapoartelor privind hibele sau ale tichetelor de semnalare a problemelor i
altele.
Mecanismul sistemului MySQL pentru furnizarea de numere unice folosete coloanele AUTO_INCREMENT.
Acestea v permit s generai automat numere n secven. Din pcate, AUTO_INCREMENT este o facilitate
uneori prost neleas, fenomen determinat poate de modificrile aduse acestei caracteristici n MySQL 3.23.
Aceast seciune descrie modul de comportare a coloanelor AUTO_INCREMENT astfel nct dumneavoastr s
le putei folosi n mod eficient, fr a cdea n capcanele care deseori iau oamenii prin surprindere. De asemenea,
seciunea v prezint modul de generare a secvenelor fr utilizarea unei coloane AUTO_INCREMENT.
AUTO_INCREMENT pentru versiunile MySQL anterioare versiunii 323
Pentru versiunile sistemului MySQL anterioare versiunii 3.23, coloanele AUTO_INCRE-MENT se comport
dup cum urmeaz:
Inseria unei valori NULL ntr-o coloan AUTO_INCREMENT determin MySQL s genereze automat
urmtorul numr din secven i s insereze n schimb acea valoare n coloan. Secvenele
AUTO_INCREMENT ncep cu l, deci prima nregistrare inserat n tabel primete n coloan o valoare
secvenial egal cu l, iar nregistrrile ulterioare primesc valori egale cu 2, 3 etc. n general, fiecare valoare
generat automat va fi cu o unitate mai mare dect valoarea maxim curent stocat n coloan.
Inseria unui O ntr-o coloan AUTO_INCREMENT este similar cu inseria valorii NULL n coloan. Inseria
unui rnd fr specificarea unei valori pentru coloana AUTO_INCREMENT este de asemenea similar cu
inseria unei valori NULL.
Dac inserai o nregistrare si specificai n mod explicit o valoare pentru coloana AUTO_INCREMENT, se va
ntmpla unul din urmtoarele dou lucruri. Dac exist deja o nregistrare cu valoarea respectiv, se va produce
o eroare, deoarece valorile din coloanele AUTO_INCREMENT trebuie s fie unice. Dac nu exist o nregistrare
cu acea valoare, nregistrarea este inserat i, dac valoarea din coloan este noua valoare maxim, secvena
continu cu valoarea urmtoare aceleia pentru rndurile ulterioare. Cu alte cuvinte, putei fora" contorul prin
inseria unei nregistrri cu o valoare din secven mai mare dect valoarea curent a contorului.
Forarea contorului poate determina goluri n secven, dar putei exploata aceast comportare n avantajul
dumneavoastr. S presupunem c ai creat un tabel cu o coloan AUTO_INCREMENT, dar dorii ca o secven
s nceap cu 1000, nu cu 1. Putei realiza acest lucru n dou moduri. Mai nti, putei insera prima nregistrare
cu o valoare de secven explicit egal cu 1000, dup care inserai nregistrrile ulterioare prin intro- | ducerea
valorii NULL n coloana AUTO_INCREMENT. n al doilea rnd, putei insera o fals '<| nregistrare n coloana
AUTO_INCREMENT, cu valoarea 999. Prima nregistrare real pe { care o inserai dup aceea va primi un
numr de secven egal cu 1000, dup care putei terge nregistrarea fals.
sy
Capitolul 2 Lucrul cu date n MySQL i SQL 113
Dac inserai o valoare incorect ntr-o coloan AUTO_INCREMENT, nu v ateptai s se ntmple ceva util.
Rezultatul nu poate fi anticipat.
Dac tergei nregistrarea care conine cea mai mare valoare dintr-o coloan AUTO_INCRE-MENT, valoarea
respectiv va fi reutilizat la urmtoarea generare a unei valori noi. Dac tergei toate nregistrrile din tabel,
vor fi refolosite toate valorile i secvena este reluat, pornind de la 1.
Instruciunile REPLACE funcioneaz normal.
Instruciunile UPDATE funcioneaz folosind reguli similare celor care se aplic inseriei de noi nregistrri.
Dac actualizai o coloan AUTO_INCREMENT cu valoarea NULL sau O, aceasta este actualizat la urmtorul
numr de secven. Dac ncercai s actualizai coloana la o valoare care exist deja, se va produce o eroare (cu
excepia situaiilor cnd se ntmpl s configurai coloana la o valoare pe care o are deja). Dac actuali-'zai
coloana la o valoare mai mare dect orice valoare existent n coloan, secvena va continua cu numrul urmtor
celui pentru nregistrrile ulterioare.
Valoarea celui mai recent numr de secven generat automat este disponibil prin apelarea funciei
LAST_INSERT_ID(). Aceasta v permite s facei referire la valoarea AUTO_INCREMENT n alte instruciuni,
fr a cunoate care este de fapt valoarea. LAST_INSERT_ID() este legat de valorile AUTO_INCREMENT
generate n timpul sesiunii curente a serverului; nu este afectat de activitatea AUTO_INCREMENT asociat cu
ali clieni. Dac nici o valoare AUTO_INCREMENT nu fost generat n timpul sesiunii curente, funcia
LAST_INSERT_ID() returneaz 0.
Posibilitatea de a genera automat numerele dintr-o secven este extrem de util. Totui, comportarea descris
anterior are dou dezavantaje. Primul: reutilizarea valorilor dintr-o secven atunci cnd sunt terse nregistrrile
din partea superioar a secvenei ngreuneaz generarea unui set de valori monotone (strict cresctoare) pentru
aplicaii care pot terge, dar care^ pot i insera nregistrri, n al doilea rnd, mijloacele prin care ncepei o
secven la o valoare mai mare dect l sunt greoaie.
AUTO_INCREMENT pentru versiunile MySQL ncepnd de la 333
MySQL 3.23 a introdus urmtoarele schimbri n comportarea atributului AUTO_INCRE-MENT n ceea ce
privete aspectele reinute anterior:
Valorile dintr-o serie generat automat sunt strict cresctoare si nu sunt refolosite. Dac valoarea maxim este
143 i dumneavoastr tergei nregistrarea care conine valoarea respectiv, MySQL va genera valoarea
urmtoare egal cu 144.
Putei specifica numrul de secven iniial n mod explicit atunci cnd creai tabelul. Exemplul urmtor
creeaz un tabel cu o coloan AUTO_INCHEMENT denumit sec, care ncepe de la valoarea 1.000.000:
CREATE TABLE tabeluljneu
(sec INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY)
AUTO_INCREMENT = 1000000
Cnd un tabel are mai multe coloane (ca majoritatea tabelelor), nu exist nici un dubiu cu privire la coloana
creia i se aplic clauza final AUTO_INCREMENT = 1000000, deoarece ntr-un tabel exist o singur coloan
AUTO_INCREMENT.
'>V/Y
' J **%**>%'
;*i-lf
i^s
114 Partea l Utilizarea general a sistemului MySQL Aspecte de reinut privind atributul
AUTO_INCREMENT
Trebuie s reinei urmtoarele elemente pentru a evita surprizele atunci cnd folosii coloane
AUTO_INCREMENT:
AUTO_INCREMENT nu este un tip de coloan; este un atribut al unui tip de coloan. Mai departe,
AUTO_INCREMENT este un atribut destinat a fi utilizat numai pentru tipuri ntregi. Versiunile de MySQL
anterioare versiunii 3.23 nu aplic aceast restricie cu strictee si v vor permite s declarai un tip de coloan
cum ar fi CHAR cu atributul AUTO_INCRE-MENT. Totui, numai tipurile ntregi funcioneaz corect drept
coloane AUTO_INCREMENT.
Scopul principal al mecanismului AUTO_INCREMENT este acela de a v permite s generai o secven de
ntregi pozitivi; cel mai indicat este s folosii coloanele AUTO_INCREMENT numai n acest mod. Din acest
motiv, trebuie s declarai coloanele AUTO_INCREMENT ca fiind UNSIGNED, ceea ce are n plus i avantajul
de a v oferi de dou ori mai multe numere n secven nainte de a ajunge la limita superioar a domeniului
tipului de coloan.
n anumite circumstane, este posibil s generai secvene de valori negative folosind o coloan
AUTO_INCREMENT, dar nu v recomand aceast operaie. Dac suntei hotrt s o ncercai, nu uitai s
efectuai testri adecvate i s re-efectuai testrile dac trecei la o versiune mai recent, diferit, de MySQL.
Propriile mele experiene au scos n eviden o comportare oarecum inconsecvent a versiunilor n ceea ce
privete secvenele de numere negative.
Nu v lsai amgit de ideea c adugarea atributului AUTO_INCREMENT la o declaraie de coloan este o
modalitate magic de a obine o secven nelimitat de numere. Nici i vorb de aa ceva; secvenele
AUTO_INCREMENT sunt limitate de domeniul tipului de] coloan. De exemplu, dac folosii o coloan
TINYINT UNSIGNED, numrul maxim de j secven este 255. Cnd ajungei la aceast limit, aplicaia
dumneavoastr va ncepe s j nregistreze erori de genul cheie duplicat".
MySQL 3.23 a introdus noile caracteristici ale atributului AUTO_INCREMENT de a tail refolosi numerele de
secven si de a v permite s specificai un numr iniial del secven n instruciunea CREATE TABLE. Aceste
caracteristici sunt anulate dac tergei;] toate nregistrrile din tabel folosind o instruciune DELETE de forma
urmtoare:
DELETE FROM nume_tabel
n acest caz, secvena va ncepe de la l, n loc s continue ntr-o ordine strict cresctoare,; Secvena reia
numrtoarea de la l chiar dac instruciunea dumneavoastr CREATEI TABLE specific n mod explicit un
numr iniial de secven. Acest lucru se produc datorit modului n care MySQL optimizeaz instruciunile
DELETE care golesc n ntregime un tabel: re-creeaz datele si fiierele index de la zero, n loc de a terge fie
nregistrare, ceea ce determin pierderea tuturor informaiilor despre numerele de secven. Dac dorii s
tergei toate nregistrrile, dar s pstrai informaiile d<| secven, putei suprima optimizarea si forai MySQL
s execute n schimb o operai^ de tergere rnd cu rnd, astfel:
DELETE FROM nume_tabel WHERE 1 > O Ce putei face pentru a pstra o serie strict cresctoare dac avei
o versiune de MySQll mai veche dect 3.23? O soluie este de a folosi un tabel separat, pe care l folosii numa
pentru generarea de valori AUTO_INCREMENT i din care nu tergei niciodat nregistrrii
*'r
*3H
Jf{
**?* -J >
j51-J j? S*. - ^ /
Capitolul 2 Lucrul cu date n MySQL i SQL 115
Astfel, valorile din tabel nu sunt refolosite niciodat. Cnd trebuie s generai o nregistrare nou n tabelul
dumneavoastr principal, mai nti inserai o valoare NULL n tabelul cu numere de secven. Apoi, inserai
nregistrarea n tabelul dumneavoastr principal folosind valoarea funciei LAST_INSERT_ID() pentru coloana
care dorii s conin un numr de secven:
INSERT INTO ai_tbl SET ai_col = NULL
INSERT INTO tbl_principal SET id=LAST_INSERT_ID(). ..
S presupunem c dorii s scriei o aplicaie care genereaz valori AUTO_INCREMENT, dar dorii ca secvena
s nceap cu 100 n loc de 1. S mai presupunem c dorii ca aplicaia s fie portabil la toate versiunile de
MySQL. Cum putei realiza acest deziderat? Dac dorii s realizai portabilitatea, nu putei conta pe faptul c
MySQL 3.23 asigur specificarea numrului de secven iniial n instruciunea CREATE TABLE, n schimb,
cnd dorii s inserai o interogare, mai nti verificai dac tabelul este gol sau nu prin emiterea urmtoarei
instruciuni:
SELECT COUNT(*) FROM nume_tabel
Aceasta este o etap suplimentar, dar care nu v cost prea mult, deoarece instruciunea SELECT COUNT(*)
fr nici o clauz WHERE este optimizat! s se execute rapid. Dac tabelul este vid, inserai nregistrarea i
specificai n mod explicit valoarea 100 pentru coloana numerelor de secven. Dac tabelul nu este vid, pur i
simplu specificai NULL pentru valoarea din coloana cu numrul de secven si permitei programului MySQL
s genereze automat urmtorul numr.
Aceast metod v permite s inserai nregistrri cu numerele de secven 100,101 si aa mai departe si
funcioneaz indiferent dac MySQL permite sau nu specificarea valorii iniiale a secvenei. Aceast abordare nu
funcioneaz dac impuneri ca numerele de secven s fie strict cresctoare chiar i atunci cnd sunt terse
nregistrri din tabel, n cazul respectiv, putei combina aceast metod cu tehnica descris anterior, de utilizare a
unui tabel secundar strict pentru generarea numerelor de secVen care vor fi folosite n tabelul dumneavoastr
principal.
De ce s ncepei o secven cu o valoare mai mare dect l ? Un motiv este de a determina toate numerele de
secven s aib acelai numr de cifre. Dac generai numere de identificare a clienilor si nu v ateptai la mai
mult de un milion de clieni, putei ncepe seria de la numrul 1.000.000. Vei putea insera cu mult peste un
milion de nregistrri ale clienilor nainte ca numrul de cifre al identificatorului de client s se modifice.
O alt modalitate de a fora o anumit dimensiune a numerelor de secven este de a folosi o coloan
ZEROFILL, desigur. Acest procedeu poate ridica probleme, n funcie de contextul n care v folosii datele. De
exemplu, dac manipulai numere de secven cu zerouri iniiale n scripturi Perl sau PHP, va trebui s le folosii
numai ca iruri; dac vor fi convertite n numere, zerourile iniiale se vor pierde. Urmtorul script Perl scurt ilus-
treaz pericolele lucrului cu numere de acest gen:
#! usr/bin/perl
$s = "00010": # creeaz "numr" cu zerouri iniiale
V>t **''*'..
-;?
prin $s++;
$s\n"
# folosete incrementul inteligent din Perl
116 Partea l Utilizarea general a sistemului MySQL
folosete $s intr-un context numeric
print "$s\n"; $s += 1; print "$s\n"; Cnd este executat, acest script afieaz urmtoarele date de ieire:
00010 OK
00011 OK
12 Hopa!
Operatorul ++ de auto-incrementare din Perl este inteligent si poate crea valori secveniale din iruri sau numere,
dar operatorul += funcioneaz numai cu numere, n datele de ieire afiate mai sus, putei vedea c operatorul
+= cauzeaz o conversie ir-numr, iar zerourile iniiale din valoarea lui $s se pierd.
Alte motive pentru a nu ncepe o secven cu l s-ar putea s nu aib nici o legtur cu anumite consideraii de
natur tehnic. De exemplu, dac atribuii numere de membru, putei dori s ncepei o secven la un numr mai
mare dect l, pentru a dejuca manevrele politice legate de identitatea membrului nr. l i pentru a v asigura c un
asemenea numr nu exist. Se mai ntmpl i aa ceva... Trist, dar adevrat.
Generarea secvenelor fr AUTO.INCREMENT
O alt metod de generare a numerelor secveniale nu folosete o coloan AUTO_INCREMENT. n schimb,
folosete forma alternativ a funciei LAST_INSERT_ID(), care preia un argument. (Aceast form a fost
introdus n MySQL 3.22.9.) Dac inserai sau actualizai o coloan folosind t_AST_INSERT_ID(expr),
urmtorul apel la LAST_INSERT_ID() fr nici un l argument va returna valoarea expr. Cu alte cuvinte, expr
este tratat ca i cum ar fi fost l generat de ctre mecanismul AUTO_INCREMENT. Aceasta v permite s
generai un numr l de secven i apoi s-1 folosii ntr-o instruciune ulterioar n cadrul sesiunii client, fr T
ca valoarea s fie afectat de ali clieni.
O modalitate de a folosi aceast strategie este de a crea un tabel cu un singur rnd,*.| coninnd o valoare care
este actualizat de fiecare dat cnd avei nevoie de urmtoarea f valoare din secven. De exemplu, putei crea
tabelul n acest mod:
CREATE TABLE sec_tabel (sec INT UNSIGNED NOT NULL)
INSERT INTO sec_tabel VALUES(O) Aceste instruciuni creeaz tabelul sec_tabel si l iniializeaz cu un
singur rnd, care conine o valoare sec egal cu 0. Pentru a folosi tabelul, generai urmtorul numr din l
secven, dup cum urmeaz:
UPDATE sec_tabel SET sec = LAST_INSERT_ID(sec+1) Aceast instruciune regsete valoarea curent a
coloanei sec i o incrementeaz cu l l pentru a genera urmtoarea valoare din secven. Generarea noii valori
folosindj LAST_INSERT_ID(sec+1) determin tratarea acesteia ca i cum ar fi fost o valoare^
AUTO_INCREMENT, iar valoarea poate fi regsit printr-o instruciune ulterioar, apelnd! funcia
LAST_INSERT_ID () fr argument. Acest procedeu funcioneaz chiar dac un ali client a generat ntre timp
un alt numr din secven, deoarece LAST_INSERT_ID() estel specific fiecrui client n parte.
" -., yi*.
^f*?.t'
Capitolul 2 Lucrul cu date n MySQL i SQL 117
De asemenea, putei folosi aceast metod dac dorii s generai valori secveniale care se incrementeaz cu o
valoare diferit de l, respectiv valori secveniale negative. De exemplu, urmtoarele dou instruciuni pot fi
folosite pentru a genera o secven de numere care cresc cu cte 100 de uniti, respectiv o secven de numere
negative:
UPDATE secjtabel SET sec = LAST_INSERT_ID(sec+100)
UPDATE secjtabel SET sec = LAST_INSERT_ID(sec-1)
Mai putei folosi aceast metod i pentru generarea unei secvene care ncepe de la o valoare arbitrar prin
stabilirea n coloana sec a unei valori iniiale adecvate.
Pentru o aplicaie a acestei metode de generare a secvenelor pentru mai multe contoare, vezi Configurarea unui
tabel contor" n capitolul 3, Sintaxa i utilizarea SQL n MySQL".
Tipuri de coloana ir
MySQL furnizeaz numeroase tipuri de iruri pentru stocarea datelor de tip caracter. irurile sunt frecvent
folosite pentru valori ca acestea:
"lonescu, Popescu & Co."
"Creioane (mina nr. 2)"
"Str. Lunga, nr. 123*
"Seria Monograph IX"
De fapt, irurile sunt ntr-un fel tipuri generice, deoarece le putei folosi pentru a reprezenta orice valoare. De
exemplu, putei folosi tipurile ir pentru a stoca date binare, cum sunt imaginile sau sunetele, respectiv date de
ieire din programul g zip, dac dorii s stocai date comprimate.
Pentru toate tipurile ir, valorile prea lungi sunt tiate" pentru a corespunde lungimii stabilite. Dar tipurile ir
variaz de la foarte mici la foarte mari, iar tipul cel mai mare poate conine aproape 4GB de date, deci trebuie s
putei gsi ceva suficient de lung pentru a evita trunchierea informaiilor dumneavoastr4.
Tabelul 2.8 prezint tipurile furnizate de MySQL pentru declararea coloanelor cu valori de tip ir, precum i
dimensiunea maxim i spaiul de stocare necesar pentru fiecare tip. Pentru tipuri de coloane cu lungime
variabil, cantitatea de spaiu ocupat de o valoare variaz de la un rnd la altul i depinde de lungimea valorilor
efectiv stocate n coloan. Aceast lungime este reprezentat n tabel prin litera L.
Octeii suplimentari necesari n afara lui L reprezint numrul de octei necesari pentru a stoca lungimea valorii.
MySQL manipuleaz valorile de lungime variabil prin stocarea att a coninutului valorii, ct i a lungimii sale.
Aceti octei suplimentari sunt tratai ca un ntreg fr semn. Observai corespondena ntre lungimea maxim a
unui tip de lungime variabil, numrul de octei suplimentari necesari pentru tipul respectiv i domeniul tipului
ntreg fr semn care folosete acelai numr de octei. De exemplu, valorile MEDIUMBLOB pot avea
maximum 224-l octei lungime si necesit 3 octei pentru nregistrarea rezultatului. Tipul ntreg pe 3 octei
MEDIUMINT are o valoare fr semn maxim de 224-l. Aceasta nu este o coinciden.
'*t\s ^
". '""'} %'' r ,, v?1gfc.
Datorit limitrilor impuse de dimensiunea maxim a pachetului n protocolul de comunicaie client/server,
limita eficace a valorilor din coloan este de 24MB. - N.A.
118 Partea l Utilizarea general a sistemului MySQL Tabelul 2.8 Tipuri de coloane ir.
Specificaia tipului
CHAR(M) VARCHAR (W) TINYBLOB, TINYTEXT BLOB, TEXT
MEDIUMBLOB, MEDIUMTEXT LONGBLOB, LONGTEXT ENUM ("val1Vval2",...) SET ("vair,"val2",...)
Dimensiune maxim
M octei u octei 28-1 octei 216-1 octei 224-1 octei 232-1 octei 65535 membri 64 membri
Spaiu necesar
W octei
L +1 octei
L +1 octei
L + 2 octei
L + 3 octei
L + 4 octei
1 sau 2 octei
1,2,3,4 sau 8 octei
Tipurile de coloane CHAR i VARCHAR
CHAR si VARCHAR sunt cele mai folosite tipuri ir. Diferena dintre ele const n aceea c CHAR este un tip
de lungime fix, iar VARCHAR este un tip de lungime variabil. Valorile dintr-o coloan CHAR (M) ocup
fiecare cte M octei; valorile mai scurte sunt completate la dreapta cu spaii atunci cnd sunt stocate. (Totui, la
regsirea acestor valori, spaiile finale sunt eliminate.) Valorile dintr-o coloan VARCHAR (M) sunt stocate
folosind numai cantitatea de octei necesar, plus un octet pentru nregistrarea lungimii5.
Dac lungimea valorilor dumneavoastr nu variaz prea mult, CHAR este o opiune mai bun dect VARCHAR,
deoarece tabelele cu rnduri de lungime fix pot fi prelucrate mai eficient dect tabelele cu lungime variabil.
Dac valorile dumneavoastr au toate aceeai lungime, VARCHAR va folosi, de fapt, un spaiu mai mare,
datorit octetului suplimentar utilizat pentru nregistrarea lungimii valorilor.
Anterior versiunii MySQL 3.23, coloanele CHAR i VARCHAR pot fi declarate cu o lungime maxim M
cuprins ntre l si 255. ncepnd de la versiunea MySQL 3.23, CHAR(O) este de asemenea o valoare permis.
CHAR(O) este util ca element de nlocuire atunci cnd dorii s declarai o coloan, dar nu vrei s alocai spaiu
pentru aceasta dac nu suntei sigur de limea pe care dorii s i-o atribuii. Putei folosi ALTER TABLE pentru
a mri ulterior limea coloanei. O coloan CHAR(O) poate fi de asemenea folosit pentru a reprezenta valorile
pornit/oprit, dac i permitei s ia valoarea NULL. Valorile dintr-o asemenea coloan pot lua dou valori, n
spe NULL si irul vid. O coloan CHAR(O) ocup un spaiu de stocare foarte redus n interiorul tabelului: un
singur bit.
Cu anumite excepii limitate, nu putei combina CHAR i VARCHAR n interiorul aceluiai tabel. MySQL va
proceda chiar la modificarea coloanelor de la un tip la altul, n funcie de circumstane. (Acesta este un lucru care
nu se ntmpl n cadrul altor sisteme de baze de date.) Principiile care se aplic sunt urmtoarele:
Tabelele cu rnduri de lungime fix sunt prelucrate mai uor dect tabelele cu rnduri de lungime variabil.
(Motivele vor fi discutate n seciunea Alegerea tipurilor de coloane".)
' Spafiile finale sunt eliminate la stocarea valorilor; acest procedeu difer de standardul ANSI pentru SQL n ceea
ce privete valorile de tip VARCHAR. - N.A.
Capitolul 2 Lucrul cu date n MySQL i SQL 119
Rndurile unui tabel au lungime fix numai dac toate coloanele din tabel sunt tipuri cu lungime fix. Dac fie
i o singur coloan are lungime variabil, rndurile tabelului devin i ele de lungime variabil.
Deoarece avantajele de performan ale rndurilor de lungime fix se pierd atunci cnd rndul devine de
lungime variabil, toate coloanele de lungime fix pot fi convertite n echivalente de lungime variabil, atunci
cnd o atare msur poate duce la economii de spaiu.
Aceasta nseamn c, dac avei coloane VARCHAR ntr-un tabel, nu putei avea i coloane CHAR; MySQL le
convertete pe tcute" n VARCHAR. S presupunem c ai creat un tabel ca acesta:
CREATE TABLE tabeluljneu
c1 CHAR(10), c2 VARCHAR(10) ) Dac emitei o interogare DESCRIBE tabeluljneu, datele de ieire se
prezint astfel:
Field Type Nuli Key Default Extra
C1 varchar(10) YES NULL
c2 varchar(10) YES NULL
Observai c prezena coloanei VARCHAR determin programul MySQL s converteasc i coloana c1 la tipul
VARCHAR. Dac ncercai s folosii ALTER TABLE pentru a converti c1 la CHAR, nu vei reui. Unica
modalitate de a transforma o coloan VARCHAR n coloan CHAR este de a converti toate coloanele
VARCHAR din tabel n acelai timp:
ALTER TABLE tabeluljneu MODIFY c1 CHAR(10), MODIFY c2 CHAR(10) Tipurile de coloane BLOB i
TEXT sunt de lungime variabil, ca i VARCHAR, dar nu au nici un echivalent de lungime fix, deci nu putei
folosi coloane CHAR n acelai tabel ca si coloanele BLOB i TEXT. Orice coloan CHAR va fi convertit la
VARCHAR.
Excepia de la regula neutilizrii n acelai tabel a coloanelor de lungime fix i a celor de lungime variabil
const n aceea c acele coloane de tip CHAR mai scurte de patru caractere nu sunt convertite la VARCHAR. De
exemplu, MySQL nu va transforma coloana CHAR din urmtorul tabel n VARCHAR: CREATE TABLE tabelul
meu
C1 CHAR(2),
c2 VARCHAR(10) )
Motivul pentru care coloanele mai scurte de patru caractere nu sunt convertite este acela c, n medie, economia
de spaiu pe care o putei obine prin nestocarea spaiilor finale este anulat de octetul suplimentar necesar ntr-o
coloan VARCHAR pentru nregistrarea lungimii fiecrei valori. De fapt, dac toate coloanele dumneavoastr
sunt scurte, MySQL va converti la CHAR orice coloan declarat ca VARCHAR. MySQL procedeaz astfel
deoarece conversia nu va mri, n medie, cantitatea de spaiu necesar i va mbunti
120 Partea l Utilizarea general a. sistemului MySQL
performanele prin transformarea rndurilor tabelului n rnduri de lungime fix. Dac creai un tabel cu
urmtoarea specificaie, coloanele VARCHAR vor fi toate convertite discret" n CHAR:
CREATE TABLE tabelul meu
c1 VARCHAR(1), C2 VARCHAR(2), C3 VARCHAR(3)
Putei verifica modificarea coloanelor prin examinarea datelor de ieire ale interogrii I DESCRIBE tabelul meu:
Field Type Nuli Key Default Extra
C1 char(1) char(2) YES NULL
c2 c3 char(3) YES NULL
YES NULL
Tipurile de coloane BLOB i TEXT
Un "BLOB" este un obiect binar mare (binary /arge object), n esen un container care poate stoca orice dorii s
punei n el i pe care l putei face aproape orict de mare i dorii, n MySQL, tipul BLOB este de fapt o familie
de tipuri (TINYBLOB, BLOB, MEDIUM-BLOB, LONGBLOB) care sunt identice, cu excepia cantitii
maxime de informaii pe care o pot stoca (vezi tabelul 2.8). MySQL mai are o familie de tipuri TEXT
(TINYTEXT, TEXT; | MEDIUMTEXT, LONQTEXT). Acestea sunt identice din toate punctele de vedere cu
tipurile i BLOB corespunztoare, cu excepia faptului c, la comparare si sortare, valorile BLOB sunt j sensibile
la diferena ntre majuscule i minuscule, n timp ce valorile TEXT nu sesizeaz J aceast diferen. Coloanele
BLOB si TEXT sunt utile pentru stocarea datelor care poi deveni foarte mari sau care pot varia foarte mult ca
dimensiune de la un rnd la altul. < Printre exemple se numr documentele create cu procesoarele de text,
imaginile sunetele, datele compuse i articolele de tiri.
Coloanele BLOB i TEXT pot fi indexate ncepnd de la MySQL 3.23.2, dei trebuie s| specificai o dimensiune
a prefixului care va fi folosit pentru index, cu scopul de a evitai intrrile de index care pot deveni enorme si care
pot, ca atare, s anuleze toate avnta?! jele dobndite prin utilizarea acelui index. De asemenea, n general nu se
efectueaz cutri n coloane BLOB sau TEXT, deoarece coloane ca acestea conin deseori date binare j (precum
imaginile). Se obinuiete mai frecvent s se utilizeze alte coloane din tabel pen-1 tru nregistrarea unui anumit
tip de informaii de identificare referitoare la valorile BLOB | sau TEXT i s se foloseasc acele informaii
pentru a determina rndurile dorite.
Coloanele BLOB i TEXT pot necesita o atenie special:
Datorit variaiilor mari caracteristice ale dimensiunilor coloanelor BLOB i TEXT, lele care le conin sunt
supuse unor fragmentri de proporii dac sunt efectuate nu? i meroase tergeri i actualizri. Va fi necesar s
rulai periodic instruciunea OPTIMIZAI TABLE pentru a reduce fragmentarea i pentru a pstra un nivel ridicat
de performanii J Vezi capitolul 4, Optimizarea interogrilor", pentru mai multe informaii. til
Capitolul 2 Lucrul cu date n MySQL i SQL 1 21
Dac folosii valori foarte mari, poate fi necesar s ajustai serverul n vederea creterii valorii parametrului
max_allowed_packet. Vezi capitolul 11, Administrarea general a sistemului MySQL", pentru mai multe
informaii. De asemenea, va trebui s mrii dimensiunea pachetului pentru orice client care dorete s foloseasc
valori foarte mari. Anexa E, Referin de programe MySQL", descrie aceast operaie pentru clienii mysql i
mysqldump.
Tipurile de coloane ENUM i SET
ENUM i SET sunt tipuri de iruri speciale pentru care valorile coloanelor trebuie alese dintr-un set fix de iruri.
Principala diferen dintre cele dou tipuri este c valorile coloanelor de tip ENUM trebuie s fie alctuite dintr-
un singur membru al setului de valori, n timp ce valorile dintr-o coloan SET pot conine oricare membru al
setului sau chiar pe toi membrii. Cu alte cuvinte, ENUM este folosit pentru valori mutual exclusive, n timp ce
SET permite mai multe opiuni dintr-o list de valori.
Tipul de coloan ENUM definete o enumerare, n coloanele ENUM se pot repartiza valori alctuite din exact un
membru ales dintr-o list de valori specificat n momentul crerii tabelului. O enumerare poate avea maximum
65536 membri (din care unul este rezervat de ctre MySQL). Enumerrile se folosesc frecvent pentru a
reprezenta valorile dintr-o categorie. De exemplu, valorile dintr-o coloan declarat ca ENUM ( "N" , "D" ) pot
fi numai "N" sau "D". Alternativ, putei folosi ENUM pentru rspunsuri la ntrebri cu opiuni multiple dintr-un
chestionar sau studiu, respectiv pentru mrimile i culorile unui produs:
salariai ENUM("sub 100", "100-500" ,"501 -1500", "peste 1500")
culoare ENUM("rosu" ," verde" /albastru", "negru")
mrime ENUM("S", "M" , "L" ,"XL" , "XXL")
Dac prelucrai selecii din pagini Web, putei folosi ENUM pentru a reprezenta opiunea pe care un vizitator al
sitului dumneavoastr o alege dintr-un set de butoane radio mutual exclusive plasate ntr-o pagin. De exemplu,
dac averi un serviciu pe Internet pentru comenzi de pizza, se poate folosi o enumerare pentru a reprezenta tipul
de coaj comandat de un client:
coaja ENUM( "subire" /normala", "stil pan")
n cazul n care categoriile de enumerare reprezint numere, este important s v alegei categoriile n mod
corespunztor atunci cnd creai enumerarea. De exemplu, cnd nregistrai numrul de leucocite rezultat n
urma unui test de laborator, putei grupa numerele n categorii n acest mod:
leucocite ENUM( "0-100" ,"101 -300" , ">300" )
Cnd rezultatul testului este dat sub forma unei valori exacte, putei nregistra valoarea sub forma categoriei n
care se ncadreaz aceasta. Nu putei ns reveni la valoarea original dac decidei s convertii coloana dintr-o
enumerare bazat pe categorii ntr-o coloan de ntregi, compus din valori exacte.
Tipul SET este similar cu ENUM n sensul c, atunci cnd creai o coloan SET, specificai o list cu nembrii
permii ai setului. Dar, spre deosebire de ENUM, fiecare valoare a coloanei poate fi alctuit din orice numr de
membri ai setului. Setul poate avea maximum 64 de membri. Putei folosi un SET atunci cnd avei un set fix de
valori care nu sunt mutual exclusive, aa cum este cazul n coloana ENUM. De exemplu, putei folosi SET
pentru a reprezenta opiunile disponibile pentru un autoturism:
,. ^Ay,,,, VJji ' 'T*-!i' >!#/
122 Partea l Utilizarea general a sistemului MySQL
SET("portbagaj","pilot automat","aer condiionat","trapa") Apoi, valorile particulare din SET vor reprezenta
opiunile efectiv comandate de clieni:
SET("pilot automat,trapa")
SET("portbagaj,aer condiionat")
SET("portbagaj,pilot automat,aer condiionat")
SET("aer condiionat")
SET("")
irul vid indic faptul c un client nu a comandat nici o opiune. Aceasta este o valoare admis pentru SET.
Valorile din coloana SET sunt reprezentate sub forma unui ir unic. Dac o valoare este alctuit din mai muli
membri ai unui set, membrii sunt separai n interiorul irului prin virgule. Evident, aceasta nseamn c nu
trebuie s folosii un ir care include o virgul ca membru al unei coloane SET.
Coloanele SET mai pot fi utilizate pentru reprezentarea unor informaii precum diagnosticele unor pacieni sau
rezultate din selecii efectuate n pagini Web. Pentru un diagnostic, poate exista o list standard de simptome a
cror (in)existen trebuie aflat de la pacient, iar acesta poate prezenta oricare simptom sau pe toate. Pentru
serviciul dumneavoastr de comenzi de pizza prin Internet, pagina Web pentru comenzi poate avea un set de
casete de validare pentru ingredientele din pizza pe care le dorete clientul, ingrediente din care se pot alege mai
multe.
Modul n care declarai lista cu valori admise pentru o coloan ENUM sau SET este important din mai multe
puncte de vedere:
Lista determin valorile admise posibile care pot fi incluse n coloan, aa cum s-a artat anterior.
Putei insera valori ENUM si SET folosind att majuscule, ct i minuscule, dar mrimea literelor pentru
irurile specificate n declaraia coloanei determin mrimea literei valorilor coloanei atunci cnd acestea sunt
regsite ulterior. De exemplu, dac avei o coloan ENUM (" D"," N") si stocai n coloan valorile " d" i" n",
valorile sunt afiate sub forma "D" i "N" atunci cnd le regsii. Acest fapt nu afecteaz comportarea tipurilor
respective la comparaie sau sortare, deoarece coloanele ENUM i SET nu sunt sensibile la diferena ntre
majuscule i minuscule.
Ordinea valorilor dintr-o declaraie ENUM este ordinea folosit pentru sortare. Ordinea valorilor dintr-o
declaraie SET determin de asemenea ordinea de sortare, dei relaia este mai complicat n acest caz, deoarece
valorile coloanelor pot conine mai muli membri ai setului.
Ordinea valorilor dintr-o declaraie SET determin ordinea n care apar sub-irurile atunci cnd sunt afiate
valorile din coloana SET care sunt alctuite din mai muli membri ai unui set.
ENUM i SET sunt clasificate ca tipuri ir, deoarece membrii enumerrii, respectiv ai setului, sunt specificai sub
form de ir atunci cnd creai coloane de aceste tipuri. Totui, membrii sunt stocai intern sub form de numere
i putei lucra cu ei ca atare. Aceasta nseamn c tipurile ENUM i SET sunt mai eficiente dect alte tipuri ir,
deoarece pot fi
Capitolul 2 Lucrul cu date n MySQL i SQL 123
manipulate frecvent folosind operaii numerice n locul operaiilor cu iruri. De asemenea, nseamn c valorile
ENUM i SET pot fi folosite att n contexte numerice, ct i n contexte cu iruri.
Membrii ENUM din declaraia coloanei sunt numerotai secvenial, ncepnd de la 1. (O este folosit de MySQL
pentru membrul eroare", care este reprezentat sub form de ir prin irul vid.) Numrul valorilor dintr-o
enumerare determin dimensiunea spaiului de stocare al unei coloane ENUM. Un octet poate reprezenta 256 de
valori, doi octei pot reprezenta 65536 de valori. (Comparai aceste valori cu domeniile tipurilor ntregi pe un
octet si pe doi octei TINYINT UNSIGNED si SMALLINT UNSIGNED.) Astfel, numrul maxim de membri ai
unei enumerri este 65536 (inclusiv membrul eroare"), iar dimensiunea spaiului de stocare depinde de
existena sau nu a unui numr de membri mai mare de 256. Putei specifica un numr maxim de 65535 (nu
65536) de membri n declaraia ENUM, deoarece MySQL rezerv un spaiu pentru membrul eroare" ca membru
implicit al fiecrei enumerri. Cnd atribuii o valoare incorect ntr-o coloan ENUM, MySQL repartizeaz n
schimb membrul eroare".
Iat un exemplu pe care l putei ncerca folosind clientul mysql. Exemplul prezint ordonarea numeric a
membrilor unei enumerri i demonstreaz, de asemenea, c valoarea NULL nu are nici un numr n cadrul
ordonrii:
mysql> CREATE TABLE e_tabel (e ENUM("ana","ion","nae","ela"));
mysql> INSERT INTO e_tabel
VALUES("ana"),("ion"),("nae"),("ela"),(""), (NULL);
mysql> SELECT e, e+0, e+1, e*3 FROM e_tabel;
e e+0 e+1 e*3
ana 1 2 3
ion 2 3 6
nae 3 4 9
ela 4 5 12
0 1 0
NULL NULL NULL NULL
Putei efectua operaii cu membrii enumerrii n funcie de nume sau de numr: mysql> SELECT e FROM
e_tabel WHERE e='nae";
nae
nae
mysql> SELECT e FROM ejtabel WHERE e=3; e
Se poate declara irul vid ca membru permis al unei enumerri. Acestui ir i se va. atribui o valoare numeric
diferit de zero, ca oricrui alt membru menionat r declaraie. Totui, utilizarea unui ir vid poate provoca
oarecare derut, deoarece irul respectiv este de asemenea folosit pentru membrul eroare", a crui valoare
numeric este 0. n exemplul urmtor, repartizarea valorii de enumerare incorecte "x" n coloana ENUM
determin
;-;^>>.
<, &i,s*>
m-
124 Partea l Utilizarea general a sistemului MySQL
repartizarea membrului de eroare. Acesta poate fi diferereniat de membrul ir vid numai atunci cnd este regsit
n form numeric:
mysql> CREATE TABLE t (e ENUM("a","",'b'));
mysql> INSERT INTO t VALUES('a"),(""),("b"),("x");
mysql> SELECT e e+0 FROM t;

Reprezentarea numeric a coloanelor SET este puin diferit de aceea a coloanelor ENUM. Membrii unui set nu
sunt numerotai secvenial, n schimb, fiecrui membru i corespunde unui bit individual n valoarea SET. Primul
membru al setului corespunde bitului O, al doilea membru corespunde bitului l etc. O valoare SET numeric
egal cu O corespunde irului vid. Membrii SET sunt stocai ca valori pe bii. n acest mod se pot stoca n fiecare
octet cte opt valori ale unui set, deci dimensiunea spaiului de stocare a unei coloane SET este determinat de
numrul de membri ai setului, pn la o valoare maxim de 64 de membri. Valorile SET pot ocupa l, 2,3,4 sau 8
octei pentru dimensiuni ale setului cuprinse respectiv ntre 1-8, 9-16, 17-24, 25-32 si 33-64.
Reprezentarea unei valori SET sub forma unui set de bii este cea care i permite unei asemenea valori s fie
alctuit din mai muli membri ai unui set. ntr-o valoare se poate stabili orice combinaie de bii, deci valoarea
poate fi alctuit din orice combinaie de iruri din declaraia SET care corespund acestor bii.
Iat un exemplu care ilustreaz relaia dintre forma ir si forma numeric a unei coloane SET; valoarea numeric
este afiat att n form zecimal, ct si n form binar:
mysql> CREATE TABLE s_tabel (s SET("ana-,"ion",-nae","ela"));
mysql> INSERT INTO s_tabel
VALUES("ana"), ("ion"), ("nae'),Cela"),("),(NULL);
mysql> SELECT s, s+0, BIN(s+0) FROM s_tabel;
s s+o BIN(s+0)
ana 1 1
ion 2 10
nae 4 100
ela 8 1000
0 0
NULL NULL NULL
Dac repartizai ntr-o coloan SET o valoare care conine sub-siruri ce nu au foti menionate ca membri ai
setului, aceste iruri sunt eliminate si n coloan este repartizat! o valoare care const din sub-irurile rmase.
Cnd repartizai valori n coloanele St,| nu este necesar ca sub-irurile s fie menionate n aceeai ordine pe
care ai folosit-oi atunci cnd ai declarat coloana. Totui, cnd regsii valoarea ulterior, membrii vor fii
menionai n ordinea de declarare. S presupunem c specificai o coloan SET pentru a| reprezenta articole de
mobilier, folosind urmtoarea declaraie:
Capitolul 2 Lucrul cu date n MySQL i SQL 125
SET("masa","lampa","scaun")
Dac repartizai n aceast coloan valoarea "scaun,canapea,masa", se vor ntmpla dou lucruri. Primul: irul
"canapea" dispare, deoarece nu este un membru al setului. Al doilea: cnd regsii valoarea ulterior, aceasta apare
sub forma" masa, scaun". Acest lucru se produce deoarece MySQL determin biii care corespund fiecrui sub-
ir al valorii care trebuie repartizate i i activeaz n cadrul valorii stocate. Sub-irul" canapea" nu corespunde
nici unui bit si este ignorat. La regsire, MySQL construiete valoarea irului din valoarea numeric prin
parcurgerea biilor n ordine, fapt care are ca efect reordonarea automat a sub-irurilor n ordinea folosit la
declararea coloanei. Aceast caracteristic mai are i urmtoarea semnificaie: dac specificai un membru al
setului de mai multe ori ntr-o valoare, acesta va aprea o singur dat la regsirea valorii. Dac repartizai
valoarea "lampa,lampa,lampa" ntr-o coloan SET, la regsire aceasta va avea numai valoarea " lampa".
Faptul c MySQL modific ordinea membrilor dintr-o valoare SET nseamn c, n cazul n care cutai valori
folosind un ir, trebuie s enumerai membrii n ordinea adecvat. Dac inserai "scaun,masa" si apoi cutai
"scaun,masa", nu vei gsi nimic; trebuie s cutai valoarea "masa, scaun".
Sortarea i indexarea coloanelor ENUM i SET se realizeaz n conformitate cu valorile interne (numerice) ale
valorilor din coloana. Exemplul urmtor ar putea prea altfel incorect, deoarece valorile nu sunt sortate n ordine
alfanumeric: mysql> SELECT e FROM e_tabel ORDER BY e;
NULL
ana ion nae ela
Valoarea NULL apare dup sortare naintea altor valori (sau dup acestea, la sortarea n ordine descendent).
Putei exploata sortarea ENUM dac avei un set fixat de valori i dorii s le sortai ntr-o anumit ordine.
Atribuii coloanei tipul ENUM cnd creai tabelul i menionai valorile din enumerare n declaraia coloanei, n
ordinea n care dorii s fie sortate.
Pentru situaii n care dorii ca o coloan ENUM s fie sortat n ordine lexicografic normal, putei converti
coloana ntr-un ir non-ENUM folosind CONCAT( )i sortnd rezultatul: mysql> SELECT CONCAT(e) AS
e_str FROM e_tabel ORDER BY e_str;
e_str NULL
ana ela ion nae
126 Partea l Utilizarea general a sistemului MySQL Atributele coloanelor de tip ir
Atributul BINARY poate fi specificat pentru tipurile CHAR i VARCHAR pentru a determina tratarea valorilor
din coloan sub form de iruri binare (adic sensibile la diferena ntre majuscule si minuscule n cazul
operaiunilor de comparare i sortare).
Atributele generale NULL sau NOT NULL pot fi specificate pentru oricare dintre tipurile ir. Dac nu specificai
nici unul din acestea, atributul prestabilit este NULL. Totui, declararea unei coloane de tip ir ca NOT NULL nu
mpiedic introducerea unui ir vid. O valoare vid este diferit de o valoare inexistent, deci nu facei greeala
de a crede c putei fora o coloan ir s conin valori nevide declarnd-o NOT NULL, n cazul n care cerei ca
valorile irurilor s fie nevide, aceasta este o restricie pe care trebuie s o impunei n cadrul propriilor
dumneavoastr aplicaii.
De asemenea, putei specifica o valoare prestabilit folosind atributul DEFAULT pentru toate coloanele de tip ir,
cu excepia tipurilor BLOB i TEXT. Dac nu specificai o valoare prestabilit, o asemenea valoare va fi aleas
n mod automat. Pentru coloanele care pot'; conine NULL, valoarea prestabilit este NULL. Pentru coloane care
nu pot conine NULL, valoarea prestabilit este irul vid, cu excepia tipului ENUM, unde valoarea prestabilit \
este primul membru al enumerrii. (Pentru SET, valoarea prestabilit ntr-o coloan care nu poate conine NULL
este de fapt setul vid, dar acesta este echivalent cu irul vid.)
Coloane de tip dat i or
MySQL furnizeaz numeroase tipuri de coloane pentru valorile temporale: DATE, DATETIME, j TIME,
TIMESTAMP i YEAR. Tabelul 2.9 prezint tipurile furnizate de MySQL pentru] declararea coloanelor care
conin valori pentru dat i or, precum i domeniul valorilor] permise pentru fiecare tip. Tipul YEAR a fost
introdus n MySQL versiunea 3.22. Celelalte j tipuri au fost prezente n toate versiunile MySQL. Dimensiunile
necesare ale spaiului dej stocare pentru fiecare tip sunt prezentate n tabelul 2.10.
Tabelul 2.9 Coloane de tip dat i or
Specificaia tipului Domeniu f
DATE ntre "1000-01-01" i "9999-12-31"
TIME ntre "-838:59:59" i "838:59:59" (
DATETIME ntre "1000-01-01 00:00:00" i "9999-12-31 23:59:59"
TIMESTAMP [(M)] ntre 19700101000000 i undeva n anul 2037
YEAR[(M)] ntre 1901 i 2155
^
Tabel 2.10 Dimensiunile spaiului de stocare necesare pentru coloanele de tip dat i oral Specificaia tipului
Dimensiuni necesare ale spaiului de stocare
DATE 3 octei (anterior versiunii MySQL 3.22,4 octei)
TIME 3 octei
DATETIME 8 OCtei
Capitolul 2 Lucrul cu date n MySQL i SQL 127
Specificaia tipului
TIMESTAMP YEAR
Dimensiuni necesare ale spaiului de stocare
4 octei 1 octet
Fiecare tip dat i or are o valoare " zero" care este stocat atunci cnd inserai o valoare care este incorect
pentru tipul respectiv, aa cum se poate vedea n tabelul 2.11. Aceast valoare este, de asemenea, valoarea
prestabilit pentru coloanele de tip dat i or care sunt declarate NOT NULL.
Tabelul 2.11 Valorile zero" pentru coloanele de tip dat i or
Specificaia tipului
DATE
TIME
DATETIME
TIMESTAMP
YEAR
Valoare zero"
"0000-00-00" "00:00:00"
"0000-00-00 00:00:00" OQOOOOOOOOOOOO 0000
MySQL reprezint ntotdeauna datele ncepnd cu anul, n conformitate cu specificaia ANSI. De exemplu, 3
decembrie 1999 este reprezentat sub forma "1999-12-03". MySQL este oarecum lejer privind modul n care
permite specificarea datelor de intrare. De exemplu, va converti valorile anilor compuse din dou cifre n valori
din patru cifre, iar dumneavoastr nu trebuie s furnizai un zero iniial pentru valorile lunilor i zilelor care sunt
mai mici dect 10. Totui, trebuie s specificai mai nti anul. Formatele cu care suntei mai obinuit, precum
"12/3/99" sau "3/12/99" vor fi interpretate incorect. Regulile folosite de MySQL pentru interpretarea datelor sunt
discutate n detaliu n paragraful Lucrul cu coloanele de tip dat i or".
Valorile de tip or sunt returnate conform fusului orar local al serverului; MySQL nu execut nici un fel de
modificri n funcie de fusul orar ale valorilor pe care le returneaz clientului.
Tipurile de coloane DATE, TIME i DATETIME
Tipurile DATE, TIME i DATETIME conin valori de date, ore i valori combinate de tip dat-or. Formatele
sunt "AAAA-LL-ZZ", "hh:mm:ss", "AAAA-LL-ZZ hh:mm:ss". Pentru tipul DATETIME, partea de dat i cea
de or sunt obligatorii; dac atribuiri o valoare DATE unei coloane DATETIME, MySQL adaug automat o parte
de or sub forma " 00:00:00".
MySQL trateaz ora din valorile DATETIME i TIME n moduri uor diferite. Pentru DATETIME, partea de or
reprezint o or din zi. Pe de alt parte, o valoare TIME reprezint timpul scurs (iat de ce domeniul este att de
mare si de ce sunt permise i valorile negative). Partea din extremitatea dreapt a valorii este considerat ca
indicnd secunde deci, dac inserai o valoare de or scurt" (incomplet definit), precum "12:30" ntr-o
coloan TIME, valoarea stocat este "00:12:30", ceea ce este interpretat sub.forma 12 minute, 30 de secunde".
Putei folosi coloanele de tip TIME pentru a reprezenta ora din zi dac dorii, dar nu uitai de aceast regul de
conversie dac dorii s evitai problemele. Pentru a insera valoarea 12 ore, 30 de minute", trebuie s o
specificai sub forma " 12:30:00".
128 Partea l Utilizarea general a sistemului MySQL Tipul de coloan TIMESTAMP
Coloanele TIMESTAMP reprezint valorile n formatul AAAALLZZhhmmss, cu un domeniu cuprins ntre
19700101000000 i undeva n anul 2037. Domeniul este legat de ora UNIX, unde prima zi din 1970 este ziua
zero", cunoscut i sub numele de epoc", nceputul lui 1970 determin extremitatea inferioar a domeniului
TIMESTAMP. Extremitatea superioar a domeniului corespunde limitei de 4 octei a orei UNIX, care poate
reprezenta valori i> anul 20376.
Tipul TIMESTAMP are aceast denumire (amprent de timp - N.T.) deoarece are proprietatea special de a
nregistra momentul crerii sau al modificrii unei nregistrri. Dac inserai o valoare NULL ntr-o coloan
TIMESTAMP, valoarea coloanei devine automat aceea a datei si orei curente. Acest lucru se ntmpl si atunci
cnd creai sau actualizai un rnd, dar nu atribuii coloanei nici o valoare explicit. Totui, numai prima coloan
TIMESTAMP dintr-un rnd este tratat n acest mod i, chiar i pentru prima coloan, putei anula aplicarea
amprentei de timp prin inseria n coloan a unei date i a unei ore explicite n locul valorii NULL.
Declaraia unei coloane TIMESTAMP poate include o specificaie pentru o lime maxim de afiare M. Tabelul
2.12 afieaz formatele de afiare pentru valorile permise ale lui M. Dac M este omis dintr-o declaraie
TIMESTAMP sau are o valoare egal cu O sau mai mare dect 14, coloana este tratat ca TIMESTAMP(14).
Valorile impare ale lui M cuprinse n intervalul 1-13 sunt asimilate urmtorului numr par imediat superior.
Tabelul 2.12 Formate de afiare pentru valorile TIMESTAMP Specificaia tipului
TIMESTAMP(14) TIMESTAMP(12) TIMESTAMP(10) TIMESTAMP(8) TIMESTAMP(6) TIMESTAMP(4)
TIMESTAMP(2)
Formatul de afiare
AAAALLZZhhmmss
AAAALLZZhhmm
AALLZZhhmm
AAAALLZZ
AALLZZ
AALL
AA
Limea de afiare pentru coloanele TIMESTAMP nu are nici o legtur cu dimensiunea spaiului de stocare sau
cu valorile stocate intern. Valorile TIMESTAMP sunt ntotdeauna stocate sub form de 4 octei i sunt folosite n
calcule cu precizie complet de 14 cifre, l indiferent de limea de afiare. Pentru a vedea acest lucru, s
presupunem ca declarai un tabel dup cum urmeaz, dup care inserai cteva rnduri n tabel i le regsii:
6 Limita superioar a valorilor TIMESTAMP va crete pe msur ce sistemele de operare vor fi modifi- J cate
pentru a extinde limita superioar a valorilor orei UNIX. Acesta este un aspect care trebuie abordat la nivelul
bibliotecii de sistem. MySQL va exploata aceste modificri pe msur ce acestea sunt efectuate. - N.A.
Capitolul 2 Lucrul cu date n MySQL i SQL 129
CREATE TABLE tabeluljneu
ts TIMESTAMP(8), i INT
INSERT INTO tabeluljneu VALUES(19990801120000,3) INSERT INTO tabeluljneu
VALUES(19990801120001,2) INSERT INTO tabeluljneu VALUES(19990801120002,1)
INSERT INTO tabeluljneu VALUES(19990801120003,0) SELECT * FROM tabeluljneu ORDER BY ts, i
Datele de ieire ale instruciunii SELECT se prezint astfel:

n aparen, rndurile sunt stocate ntr-o ordine greit - valorile din prima coloan sunt toate identice, deci se
pare c sortarea ar trebui s aranjeze rndurile n conformitate cu valorile din a doua coloan. Acest rezultat
aparent anormal se datoreaz faptului c MySQL sorteaz n funcie de valorile complete, cu 14 cifre, inserate n
coloana TIMESTAMP.
MySQL nu are nici un tip de coloane care s primeasc data i ora crerii nregistrrii i care s rmn imuabil
dup aceea. Dac dorii s realizai acest lucru, putei proceda n dou moduri:
Folosii o coloana TIMESTAMP. Cnd nregistrarea este creat pentru prima dat, atribuii coloanei valoarea
NULL pentru a o iniializa cu valoarea datei si a orei curente:
INSERT INTO nume_tabel (ts_col, ...) VALUES(NULL, ...) De fiecare dat cnd actualizai nregistrarea la o
dat ulterioar, atribuii n mod explicit coloanei valoarea pe care o are deja. Prin atribuirea unei valori explicite
se contracareaz mecanismul de aplicare a amprentei de timp, deoarece mpiedic actualizarea automat a valorii
coloanei:
UPDATE nume_tabel SET ts_col=ts_col WHERE ...
Folosii o coloan DATETIME. Cnd creai o nregistrare, iniializai coloana la valoarea NOW():
INSERT INTO nume_tabel (dt_col, ...) VALUES(NOW(), ...) La fiecare actualizare ulterioar a nregistrrii,
lsai coloana nemodificat:
UPDATE nutne_tabel SET /* orice IN AFARA DE coloana dt_col */ WHERE ... Dac dorii s folosii coloanele
TIMESTAMP pentru a pstra att o valoare a orei crerii, ct i a orei ultimei modificri, puteri face aceasta
folosind o coloan TIMESTAMP pentru valoarea orei modificrii, respectiv o alt coloan TIMESTAMP pentru
valoarea orei crerii. Verificai ca ora modificrii s fie inclus n prima coloan TIMESTAMP, astfel nct s fie
configurat cnd nregistrarea este creat sau modificat. Facei din coloana cu ora crerii cea de-a doua coloan
TIMESTAMP si iniializati-o la valoarea NOW() atunci cnd creai nregistrri noi. Astfel, valoarea sa va
reflecta momentul crerii nregistrrii i nu se va modifica ulterior.
v'tt&
. fif"
130 Partea l Utilizarea general a sistemului MySQL Tipul de coloan YEAR
YEAR este un tip de coloan pe un octet folosit pentru reprezentarea eficient a valorilor anilor. Domeniul de
valori este cuprins ntre 1901 i 2155. Putei folosi tipul YEAR atunci cnd dorii s stocai informaii despre
date calendaristice, dar avei nevoie numai de an, cum ar fi anul naterii, anul alegerii n funcia de preedinte si
altele. Cnd nu avei nevoie de o valoare de tip dat complet, YEAR este mult mai eficient din punctul de
vedere al spaiului utilizat dect alte tipuri de date.
Declaraia unei coloane YEAR poate include o specificare a limii de afiare M, care poate fi 4 sau 2. Dac M
este omis dintr-o declaraie de tip YEAR, valoarea prestabilit este 4.
TINYINT are aceeai dimensiune a spaiului de stocare ca si YEAR (un octet), dar nu i acelai domeniu. Pentru
a acoperi aceeai perioad de timp ca i YEAR folosind un tip ntreg, avei nevoie de un SMALLINT, care
necesit o cantitate dubl de spaiu. Dac intervalul de timp n ani pe care trebuie s-1 reprezentai coincide cu
domeniul tipului YEAR, cel din urm folosete spaiul ntr-un mod mai eficient dect SMALLINT. Un alt
avantaj al coloanei YEAR fa de o coloan cu valori ntregi este acela c MySQL va conveni valorile din dou
cifre n valori cu patru cifre, folosind regulile obinuite de ghicire" a anului din MySQL. De exemplu, 97 i 14
devin 1997, respectiv 2014. Totui, reinei c inseria valorii numerice 00 va avea ca rezultat stocarea valorii
0000, nu a valprii 2000. Dac dorii ca o valoare zero s fie convertit la 2000, trebuie s o specificai sub form
deir: "00".
Atributele coloanelor de tip dat i or
Nu exist nici un atribut specific coloanelor de tip dat i or. Atributele generale NULL sau J NOT NULL pot fi
specificate pentru oricare dintre tipurile dat i or. Dac nu specificai nicijj unul din aceste atribute, NULL este
cel prestabilit. De asemenea, putei specifica o valoare| prestabilit folosind atributul DEFAULT. Dac nu
specificai o valoare prestabilit, o aseme-| nea valoare va fi aleas automat. Valoarea prestabilit este NULL
pentru coloanele care pot conine NULL, n caz contrar, valoarea prestabilit pentru tipul respectiv este zero".
Lucrul cu coloane de tip dat i or
MySQL ncearc s interpreteze valorile de tip dat i or ntr-o varietate de formatei Valorile DATE pot fi
specificate n oricare din urmtoarele formate, inclusiv formele ir : numerice. Tabelul 2.13 prezint formatele
permise pentru fiecare dintre tipurile dat i or
Tabelul 2.13 Formate de intrare pentru coloanele de tip dat si or Tip
DATETIME, TIMESTAMP
Formate permise
AAAA-LL-ZZ hh:mm:ss" "AA-LL-ZZ hh:mm:ss" "AAAALLZZhhmmss" " AALLZZhhmmss"
AAAALLZZhhmmss AALLZZhhmmss
Capitolul 2 Lucrul cu date n MySQL i SQL 131
Tip
DATE
TIME
YEAR
Formate permise
"AAAA-Ll-ZZ"
"AA-LL-ZZ"
"AAAALLZZ"
"AALLZZ"
AAAALLZZ
AALLZZ
"hh:mm:ss"
"hhmmss"
hhmmss
11AA"
AAAA
AA
Formatele cu dou cifre pentru valoarea anului sunt interpretate folosind regulile descrise n seciunea
Interpretarea valorilor ambigui ale anilor". Pentru formate de tip ir care includ caractere de delimitare, nu
trebuie s folosii cratimele pentru date, respectiv caracterul dou puncte pentru ore. Ca delimitator poate fi
folosit orice semn de punctuaie. Interpretarea valorilor depinde de context, nu de delimitator. De exemplu, dei
orele sunt specificate de obicei folosind delimitatorul dou puncte, MySQL nu va interpreta o valoare care
conine acest caracter ca o or ntr-un context unde se ateapt o dat. n plus, pentru formatele de tip ir care
includ delimitatori, nu trebuie s specificai dou cifre pentru valorile lunilor, zilelor, orelor, minutelor sau
secundelor care sunt mai mici dect 10. Urmtoarele formate sunt toate echivalente ntre ele:
"2012-02-03 05:04:09" '
"2012-2-03 05:04:09"
"2012-2-3 05:04:09"
"2012-2-3 5:04:09"
"2012-2-3 5:4:09"
"2012-2-3 5:4:9"
Observai c valorile cu zerouri iniiale pot fi interpretate diferit, n funcie de faptul dac sunt specificate ca
iruri sau ca numere. irul "001231" va fi vzut ca o valoare cu ase cifre si va fi interpretat sub forma "2000-12-
31" pentru o coloan DATE, respectiv ca " 2000 -12 - 31 00:00:00" pentru o coloan DATETIME. Pe de alt
parte, numrul 001231 va fi asimilat cu 1231 dup ce a trecut" prin analizor, moment dup care interpretarea
devine problematic. Aceasta este o situaie unde cel mai bine este s furnizai o valoare de tip ir sau s folosii
o valoare complet determinat n cazul n care utilizai numere (adic 20001231 pentru DATE, respectiv
200012310000 pentru DATETIME).
n general, putei atribui la discreie valori ntre tipurile DATE, DATETIME si TIMESTAMP,
dei trebuie s inei cont de anumite restricii:
Dac repartizai o valoare DATETIME sau TIMESTAMP ntr-o coloan DATE, partea de or
este eliminat.

132 Partea l Utilizarea general a sistemului MySQL


Dac repartizai o valoare DATE ntr-o coloan DATETIME sau TIMESTAMP, partea de or a valorii
rezultante primete valoarea zero.
Tipurile respective au domenii diferite, n particular, TIMESTAMP are un domeniu mai limitat (ntre 1970 si
2037) deci, de exemplu, nu putei repartiza o valoare DATETIME anterioar lui 1970 ntr-o coloan
TIMESTAMP si s v ateptai la rezultate rezonabile. De asemenea, ntr-o coloan TIMESTAMP nu putei plasa
valori din viitorul ndeprtat.
MySQL furnizeaz multe funcii pentru lucrul cu valorile de tip dat i or. Pentru mai multe informaii, vezi
Anexa C.
Interpretarea valorilor ambigue ale anilor
Pentru toate coloanele de tip dat si or care includ o parte care conine anul (DATE, DATETIME,
TIMESTAMP, YEAR), MySQL manipuleaz valori care conin ani exprimai prin dou cifre convertind aceste
valori n ani exprimai cu patru cifre. Aceast conversie se produce n conformitate cu urmtoarele reguli7:
Valorile anilor cuprinse ntre 00 i 69 se transform n valori din intervalul 2000-2069
Valorile anilor cuprinse ntre 70 si 99 se transform n valori din intervalul 1970-1999
Putei vedea cel mai uor efectul acestor reguli prin repartizarea a dou valori cu dou cifre diferite ntr-o
coloan YEAR si apoi regsind rezultatele. De asemenea, exemplul va scoate n eviden ceva ce merit reinut:
mysql> CREATE TABLE y_tabel (y YEAR);
mysql> INSERT INTO yjtabel VALUES(68),(69),(99), (00);
mysql> SELECT * FROM y_tabel;
2068 1969 1999 0000
Observai c 00 a fost convertit n 0000, nu n 2000. Aceasta deoarece O este o valoare absolut corect pentru
tipul YEAR; dac inserai un zero numeric, atunci vei obine un| zero numeric. Pentru a obine 2000, inserai
irul "O" sau "00". V putei asigura MySQL vede" un ir si nu un numr prin inseria valorilor YEAR folosind
CONCAT ()j Aceast funcie returneaz ntotdeauna un rezultat ir, indiferent dac argumentul sli este un ir
sau un numr.
n orice caz, reinei c regulile pentru conversia anilor compui din dou cifre n compui din patru cifre asigur
numai intuirea n limite rezonabile a valorii. Nu exist nici o modalitate ca MySQL s fie sigur de semnificaia
unui an exprimat prin dou cifrB atunci cnd nu se specific secolul. Dac regulile de conversie din MySQL nu
genere valorile dorite, soluia este evident: furnizai date fr echivoc, cu ani exprimai prii patru cifre.
7 n MySQL 4.0, regulile vor suferi o oarecare schimbare, prin aceea c 69 va fi convertit n 1969,: n 2069, n
conformitate cu regulile specificate prin standardul UNIX X/Open. - N .A.
Capitolul 2 Lucrul cu date n MySQL i SQL 133
Alegerea tipurilor de coloan
Seciunea anterioar descrie diferitele tipuri de coloane MySQL din care putei alege, precum si proprietile
generale ale acestor tipuri, ca tipurile de valori pe care le pot conine, cantitatea de spaiu de stocare pe care o pot
ocupa i altele. Dar cum alegei tipurile de coloane pe care le vei folosi cnd creai un tabel? Aceast seciune
discut despre aspectele care trebuie avute n vedere pentru a v ajuta s alegei.
Cele mai generale" tipuri de coloane sunt tipurile ir. n aceste coloane putei stoca orice, deoarece numerele si
datele pot fi reprezentate sub form de ir. Deci, de ce n-ai declara toate coloanele sub form de iruri i s
terminai povestea? S ne gndim la un singur exemplu. S presupunem c avei valori care arat ca nite
numere. Le putei reprezenta ca numere, dar chiar trebuie s o facei? Ce se ntmpl dac procedai astfel?
n primul rnd, probabil c vei folosi o cantitate mai mare de spaiu, deoarece numerele pot fi stocate ntr-un
mod mult mai eficient dect irurile. De asemenea, vei remarca unele diferene ntre rezultatele interogrilor,
datorit modalitilor diferite de manipulare a irurilor i a numerelor. De exemplu, ordinea de sortare pentru
numere nu este aceeai ca pentru iruri. Numrul 2 este mai mic dect numrul 11, dar irul "2" este, din punct
de vedere lexicografic, mai mare dect irul "11". Putei rezolva aceast problem folosind coloana ntr-un
context numeric, ca acesta: SELECT nume_coloana + O AS num... ORDER BY num
MySQL ore problema anului 2000"?
MySQL nu are problema anului 2000, deoarece stocheaz datele intern sub form de ani cu patru cifre, dar este
rspunderea dumneavoastr s furnizai de la bun nceput date care s aib ca rezultat stocarea valorilor
adecvate. Adevrata problem cu interpretarea anilor cu dou cifre nu este dat de MySQL, ci de dorina uman
de a o lua pe scurttur" i de a furniza date echivoce. Dac dorii s v asumai riscul, suntei liber s o facei.
Este riscul dumneavoastr, iar regulile de determinare a anului din MySQL sunt adecvate n multe situaii. Este
bine s tii, ns, c exist situaii cnd trebuie s introducei ani din patru cifre. De exemplu, pentru a introduce
datele de natere i de deces n tabelul preedinte, care conine preedinii americani ncepnd din secolul al
XVIII-lea, se impune utilizarea a patru cifre. Valorile din aceste coloane acoper mai multe secole, deci a lsa
MySQL s .ghiceasc" secolul pe baza unui an din dou cifre este categoric o opiune eronat.
Prin adugarea unui zero la coloan se foreaz o sortare numeric, dar este oare rezonabil? n general, probabil
c nu. A determina MySQL s trateze coloana ca pe un numr, nu ca pe un ir, are cteva implicaii importante.
Se foreaz o conversie ir-numr pentru fiecare valoare din coloan, ceea ce este ineficient. De asemenea,
transformarea coloanei ntr-o coloan cu valori calculate mpiedic MySQL s foloseasc un index pentru
coloan, ceea ce reduce i mai mult viteza interogrii. Nici una din aceste degradri ale performanei nu se va
produce dac stocai de la bun nceput valorile sub form de numere. Simpla opiune de a folosi o reprezentare n
locul alteia are implicaii pentru cerinele privind dimensiunea spaiului de stocare, manipularea interogrilor i
performanele de prelucrare.
134 Partea l Utilizarea general a sistemului MySQL
Exemplul anterior ilustreaz faptul c la alegerea tipurilor de coloane intr n joc mai muli factori. Lista
urmtoare parcurge rapid factorii la care trebuie s v gndii atunci cnd selectai un tip pentru o coloan.
Ce tip de valori va conine coloana? Numere? iruri? Date calendaristice? Aceasta este o ntrebare evident, dar
trebuie s o punei. Putei reprezenta orice tip de valoare sub form de ir, dar, aa cum am vzut anterior,
probabil vei obine performane superioare dac folosii alte tipuri mai adecvate pentru valorile numerice. (Acest
lucru este de asemenea valabil pentru valorile de tip dat i or.) Totui, evaluarea tipului de valori cu care lucrai
nu este n mod obligatoriu ceva banal, mai ales dac este vorba despre datele altcuiva. Este deosebit de important
s ntrebai care este tipul de valori pe care l vor conine coloanele n cazul n care configurai un tabel pentru
altcineva si trebuie s fii sigur c punei destule ntrebri cu scopul de a primi suficiente informaii pentru a lua
o decizie inspirat.
Valorile dumneavoastr se gsesc ntr-un anumit domeniu particular? Dac sunt ntregi, vor fi ntotdeauna
diferite de zero? Dac da, putei folosi UNSIGNED. Dac sunt iruri, vor fi ntotdeauna selectate dintr-un set
fixat de valori? Dac da, vei gsi util tipul ENUM sau SET.
Exist un compromis ntre domeniul unui tip i cantitatea de spaiu de stocare pe care o folosete. Ct de mare"
este tipul de care avei nevoie? Pentru numere, putei alege i tipuri mici, cu un domeniu limitat de valori,
respectiv tipuri mari, care sunt, n esen, j nelimitate. Pentru iruri, le putei face scurte sau lungi i nu vei alege
declaraia] CHAR (255) dac toate valorile pe care dorii s le stocai conin mai puin de l O caractere, i
Care sunt aspectele legate de performan i eficien? Unele tipuri pot fi prelucrate | mai eficient dect altele.
Operaiile numerice, n general, pot fi efectuate mai rapidl dect operaiile cu iruri. irurile scurte pot fi
comparate mai uor dect irurile lungii i implic, de asemenea, o suprasarcin mai redus asupra discului.
Performanele sunt mai ridicate pentru tipurile de lungime fix dect pentru cele de lungime variabil.
Cum dorii s fie comparate valorile dumneavoastr? Pentru iruri, comparaiite| pot sesiza sau nu diferena
ntre majuscule i minuscule. Aici, opiunile dumneavoas/ tr mai pot afecta i sortarea, care este bazat pe
comparaii.
Intenionai s indexai o coloan? Dac da, acest lucru influeneaz opiunea dum-l neavoastr privind tipul
coloanei, deoarece unele versiuni de MySQL nu v permit si indexai anumite tipuri, precum BLOB i TEXT. De
asemenea, unele versiuni de MyS( impun ca o coloan indexat s fie declarat ca NOT NULL, ceea ce
afecteaz posibilitatea dumneavoastr de a folosi valori NULL.
Acum, s lum n considerare fiecare dintre aceste probleme n detaliu. Dar, nainte de trece la fapte, permitei-
mi un punct de vedere: dorii s facei cele mai bune alegeri posif bile privind tipurile de coloane atunci cnd
creai un tabel, dar, dac facei o alegere ca nu se dovedete a fi optim, nu este sfritul lumii. Putei folosi
ALTER TABLE pentru l nlocui tipul cu unul mai bun, ceea ce se poate reduce la nlocuirea unui SMALLINT cu
MEDIUMINT dup ce ai descoperit c datele dumneavoastr conin valori mai mari de cele la care v-ai gndit
iniial. Aceast operaie poate fi, ns, complicat, cum ar nlocuirea unui CHAR cu un ENUM cu un set bine
precizat de valori permise, n MySQL 3.:
Capitolul 2 Lucrul cu date n MySQL i SQL 135
i versiunile ulterioare, putei folosi PROCEDURE ANALYSE() pentru a obine informaii despre coloanele
tabelului dumneavoastr, cum ar fi valorile minime si maxime, precum i un tip optim propus care s acopere
domeniul de valori dintr-o coloan. Aceast funcie v poate ajuta s concluzionai c se poate folosi un tip mai
mic, care poate mbunti performanele interogrilor care implic tabelul si care reduce cantitatea de spaiu
necesar pentru stocarea tabelului.
Ce tip de valori va conine coloana?
Primul lucru la care v gndii atunci cnd ncercai s v decidei asupra unui tip de coloan este genul de valori
pentru care va fi folosit coloana, deoarece acesta este faptul cu implicaiile cele mai evidente pentru tipul pe
care l alegei, n general, procedai ntr-un mod previzibil: stocai numerele n coloane numerice, irurile n
coloanele ir, respectiv datele si orele n coloane de tip dat si or. Dac numerele dumneavoastr au o parte
fracionar, vei folosi un tip de coloan cu virgul mobil n locul unui tip ntreg i aa mai departe. Uneori
exist i excepii. Aici, principiul este c trebuie s nelegei natura datelor dumneavoastr, pentru a fi capabil s
alegei tipul de coloan ntr-o manier informat". Dac v vei stoca propriile date, probabil c tii bine cum
s le caracterizai. Pe de alt parte, dac alte persoane v solicit s le configurai un tabel, uneori datele
problemei se schimb. S-ar putea s nu aflai prea uor care sunt elementele pe care le folosii. Nu uitai s punei
suficiente ntrebri pentru a afla tipurile de valori pe care trebuie s le conin tabelul.
S presupunem c vi se spune c o coloan trebuie s stocheze cantitatea de precipitaii". Este vorba de un
numr? Sau este n cea mai mare parte" numeric - adic de regul, dar nu ntotdeauna, este codificat sub forma
unui numr? De exemplu, cnd urmrii tirile la televizor, buletinul meteorologic include, n general, o msur a
precipitaiilor. Uneori este vorba de un numr (de exemplu 6 mm de ploaie"), dar alteori este o urm" de pre-
cipitaii, ceea ce nseamn foarte puin". Toate bune i frumoase n ceea ce privete buletinul meteorologic, dar
ce nseamn asta pentru stocarea ntr-o baz de date? Fie trebuie s cuantificai noiunea de urm" sub forma
unui numr, astfel nct s putei folosi o coloan numeric pentru a nregistra cantitile de precipitaii, fie
trebuie s folosii un ir, astfel nct s putei nregistra cuvntul urm". Alternativ, putei veni cu un aranjament
mai complicat, folosind o coloan numeric i o coloan ir, caz n care completai o coloan si inserai n
cealalt valoarea NULL. Este evident c dorii s evitai acea opiune, dac este posibil; tabelul ar deveni mai
dificil de neles si ngreuneaz semnificativ scrierea interogrilor.
Probabil c eu as ncerca s stochez toate rndurile n format numeric i apoi s le convertesc conform
necesitilor de afiare. De exemplu, dac orice cantitate de precipitaii mai mic de 0,25 mm, dar diferit de
zero, este considerat o cantitate de tip urm", putei afia valori din coloan astfel:
SELECT IF(precip>0 AND precip<.25, "urma" .precip) FROM ...
,.,-*'
" !;
"O?
136 Partea l Utilizarea general a sistemului MySQL
Pentru calcule monetare, lucrai cu valori care conin dolari i ceni8. Acestea par a fi valori cu virgul mobil,
dar FLOAT i DOUBLE sunt supuse la erori prin rotunjire i pot fi inadecvate, cu excepia nregistrrilor n care
avei nevoie numai de o precizie aproximativ. Deoarece oamenii sunt destul de sensibili cnd este vorba de
banii lor, probabil c vei avea nevoie de un tip de coloane care s permit o precizie perfect. Avei la dispoziie
cteva opiuni:
Putei reprezenta sumele de bani ca un tip DECIMAL(M, 2), alegnd M ca lime maxim adecvat pentru
domeniul de valori de care avei nevoie. Astfel, obinei valori cu virgul mobil cu precizie de dou cifre dup
virgul. Avantajul tipului DECIMAL este acela c valorile sunt reprezentate sub form de iruri i nu sunt supuse
erorilor prin rotunjire. Dezavantajul este c operaiile cu iruri sunt mai puin eficiente dect cele cu valori
reprezentate intern sub form de numere.
Putei reprezenta intern toate valorile monetare sub form de ceni, folosind un tip ntreg. Avantajul este c
toate calculele sunt efectuate intern folosind ntregi, ceea ce determin o mare vitez de calcul. Dezavantajul este
c va trebui s convertii valorile la intrare sau ieire, prin nmulire sau mprire la 100.
Unele valori sunt n mod evident numerice, dar trebuie s determinai dac vei folosi un tip ntreg sau cu virgul
mobil. Trebuie s ntrebai care sunt unitile de msur i precizia cerut. Precizia dat de unitile ntregi este
suficient sau trebuie s reprezen-* tai i uniti fracionare? Aceast ntrebare v poate ajuta s facei diferena
dintre j tipurile de coloan ntregi i cele cu virgul mobil. De exemplu, dac reprezentaii greuti, putei folosi
o coloan cu valori ntregi dac nregistrai valorile pn la cea mai l apropiat cantitate exprimat n kilograme.
Vei folosi o coloan cu virgul mobil daci l dorii s nregistrai uniti fracionare, n unele situaii, putei
folosi chiar i cmpuri j multiple, de exemplu dac dorii s nregistrai greutatea n kilograme si grame,
nlimea este un alt tip numeric de informaii pentru care exist numeroase posibilitii de reprezentare:
JJ
Un ir de genul "6-2" pentru o valoare de genul 6 picioare i 2 inch9". Aceastifj opiune are avantajul de a
avea o form simplu de examinat side neles (categoric ma| simpl dect 74 inch"), dar aceast categorie de
valori este mai dificil de utilizat pent operaii matematice, precum nsumarea sau calculul mediei.
Un cmp numeric pentru valorile exprimate n picioare i altul pentru valoriUj exprimate n inch. Aceasta este
o form ceva mai uor de ntrebuinat pentru
iile matematice, dar dou cmpuri sunt mai dificil de folosit dect unul singur.
Un cmp numeric reprezentnd valorile n inch. Este cel mai uor de utilizat ctre o baz de date, dar cel mai
greu de neles pentru oameni. Dar nu uitai c nu i buie s prezentai valorile n formatul pe care l folosii
pentru a lucra cu ele. Pute|| reformata valorile pentru o afiare mai semnificativ folosind numeroasele funcii
8 Am preferat s pstrm textul original, deoarece marea" noastr moned naional a ajuns att < mic, nct
vorbind despre lei i bani (adic a suta parte dintr-un leu) n momentul actual riscm i nu producem dect rsul
(amar sau ironic) al cititorului romn... N.T.
9 In sistemul metric anglo-saxon, uniti de msur a lungimii, l picior = 33 cm, l inch = 2,54 cm. - N.
Capitolul 2 Lucrul cu date n MySQL i SQL 137
sistemului MySQL. Aceasta nseamn c opiunea de fa este cea mai bun modalitate de reprezentare a
nlimii.
Dac trebuie s stocai informaii despre date calendaristice, valorile respective includ i ora? Cu alte cuvinte, va
fi vreodat nevoie s includ i ora? MySQL nu furnizeaz un tip de date care s aib o parte opional pentru
or: DATE nu are niciodat o or, iar DATE -TIME trebuie s aib o or. Dac ora este ntr-adevr opional,
folosii o coloan DATE pentru a nregistra data, respectiv o coloan TIME separat pentru a include ora. Apoi
permitei coloanei TIME s ia valoarea NULL si interpretai aceast valoare ca fr or": CREATE TABEL
tabelul meu
data DATE NOT NULL,
ora TIME NULL )
Un tip de situaie cnd este deosebit de important s determinai dac avei sau nu nevoie de o valoare a orei se
produce atunci cnd unii dou tabele cu o relaie de tip master-detaliu, tabele care sunt legate" n funcie de
informaiile legate de dat.
S presupunem c suntei coordonatorul unei activiti de cercetare care implic subieci ce intr n biroul
dumneavoastr pentru a fi testai. Dup un set iniial standard de teste, putei efectua mai multe teste
suplimentare n aceeai zi, unde opiunea testelor variaz n funcie de rezultatele testelor iniiale. Putei
reprezenta aceste informaii folosind o relaie master-detaliu, n care informaiile de identificare a subiectului i
testele standard iniiale sunt stocate ntr-o nregistrare mater, iar toate testele suplimentare sunt stocate sub
form de rnduri ntr-un tabel secundar cu detalii. Apoi, corelai cele dou tabele n funcie de identificatorul
subiectului i data la care au avut loc testele.
ntrebarea la care trebuie s rspundei n aceast situaie este dac putei folosi numai data sau dac v trebuie
att data, ct i ora. Acest lucru depinde de faptul dac un subiect poate parcurge procedura de testare de mai
multe ori, pe durata aceleiai zile. Dac da, nregistrai ora (de exemplu ora la care ncepe procedura) folosind fie
o coloan DATETIME, fie coloane DATE i TIME separate, care trebuie completate amndou. Fr valoarea
orei, nu vei putea asocia nregistrrile detaliu ale unui subiect cu nregistrrile mater adecvate dac subiectul a
fost testat de dou ori ntr-o zi.
Am auzit oameni spunnd: N-am nevoie de or; nu voi testa niciodat un subiect de dou ori n aceeai zi."
Uneori au dreptate, dar i-am vzut pe o parte din aceiai oameni ajungnd ulterior s se ntrebe cum pot preveni
asocierea nregistrrilor detaliu cu o nregistrare mater greit, dup ce au introdus date pentru subieci care au
fost testai de mai multe ori ntr-o zi. Scuze, dar atunci e prea trziu!
Uneori putei rezolva aceast problem prin inseria/>ort/*rtm n tabele a unei coloane TIME. Din pcate,
nregistrrile existente sunt dificil de remediat, cu excepia situaiilor cnd avei o surs independent de date,
cum sunt nregistrrile originale scrise. Altfel, nu avei nici o modalitate de a clarifica misterul" nregistrrilor
detaliu ambigui, pentru a le asocia cu nregistrarea mater adecvat. Chiar dac avei o surs independent de
informaii, aceasta este o operaie ncurcat i poate cauza probleme aplicaiilor pe care le-ai scris deja cu scopul
de a utiliza tabelele. Cel mai bine este s explicai problema
138 Partea l Utilizarea general a sistemului MySQL
posesorilor tabelelor i s v asigurai c dispunei de o bun caracterizare a valorilor datelor nainte de a le crea
tabelele.
Uneori putei avea date incomplete, lucru ce poate influena opiunea dumneavoastr privind tipurile de coloane.
De exemplu, adunai date de natere si deces pentru cercetri de natur genealogic, iar uneori tot ce putei afla
este anul n care cineva s-a nscut sau a decedat, nu i data exact. Dac folosii o coloan DATE, nu putei
introduce o dat dect dac dispunei de toate elementele acesteia. Dac dorii s putei nregistra informaiile pe
care le avei, oricare ar fi acestea, chiar dac sunt incomplete, s-ar putea s fii obligat s folosii cmpuri
separate pentru an, lun i zi. Apoi putei introduce prile de informaii pe care le avei si inserai valoarea
NULL pentru celelalte informaii, n MySQL 3.23 si versiunile ulterioare exist si o alt posibilitate, care permite
prilor care conin ziua, respectiv luna i data, s ia valoarea 0. Asemenea date neclare" pot fi folosite pentru a
reprezenta valori de date incomplete.
Valorile dumneavoastr se ncadreaz ntr-un anumit domeniu?
Dac v-ai oprit asupra unei categorii generale din care s selectai un tip pentru o coloan, stabilirea domeniului
de valori pe care dorii s-1 reprezentai v va ajuta s reducei plaja de opiuni la un anumit tip din cadrul acelei
categorii. S presupunem c dorii s stocai valori ntregi. Domeniul valorilor dumneavoastr determin tipurile
pe care le putei folosi. Dac avei nevoie de valori n domeniul 0-1000, putei folosi orice tip cuprins ntre
SMALLINT i BIGINT. Dac valorile dumneavoastr ajung pn la dou milioane, nu putei folosi SMALLINT,
iar opiunile dumneavoastr variaz de la MEDIUMINT la BIGINT. Apoi, trebuie s selectai un tip dintre
posibilitile existente.
Putei, desigur, s folosii pur si simplu cel mai mare tip pentru categoria de valoare pe care dorii s o stocai
(BIGINT pentru exemplele din paragraful anterior), n general, totui, trebuie s folosii cel mai mic tip care este
suficient de mare pentru inteniile; dumneavoastr. Procednd astfel, vei reduce la minimum cantitatea de spaiu
folosit de tabelele dumneavoastr, iar acestea v vor oferi performane superioare, deoarece coloanele mai mici
pot fi, de obicei, prelucrate mai rapid dect coloanele mai mari.
Dac nu cunoatei domeniul de valori pe care va trebui s-1 putei reprezenta, trebuie; s v folosii intuiia sau
s utilizai BIGINT pentru a lua n calcul cel mai ru caz cuj putin. (Reinei c, dac v dai cu prerea si
folosii un tip care se dovedete a fi prea| mic, nu este totul pierdut; putei folosi mai trziu ALTER TABLE
pentru a face coloana m; ncptoare".)
n capitolul l, am creat un tabel puncte pentru proiectul de eviden a rezultatelor co care coninea o coloan
puncte pentru nregistrarea punctajelor obinute la chestionare i teste. Tabelul fusese creat folosind I NT pentru a
pstra simplitatea expunerii, dar putei vedea c, dac punctajele se afl n domeniul 0-100, o opiune mai bun
ar fi TINYI UNSIGNED, deoarece ar folosi un spaiu de stocare mai redus.
Domeniul de valori din datele dumneavoastr influeneaz de asemenea atributele pe caife le putei folosi pentru
tipul coloanei dumneavoastr. Dac valorile nu sunt niciodat in gative, putei folosi UNSIGNED; n caz contrar,
nu putei.
Capitolul 2 Lucrul cu date n MySQL i SQL 139
Tipurile ir nu au un domeniu" n sensul domeniului coloanelor numerice, dar ele au o lungime, iar lungimea
maxim de care avei nevoie afecteaz tipurile de coloane pe care le putei folosi. Dac irurile dumneavoastr
sunt mai scurte de 256 caractere, putei folosi CHAR, VARCHAR, TINYTEXT sau TINYBLOB. Dac avei
nevoie de iruri mai lungi, putei folosi un tip TEXT sau BLOB, dar asta nseamn c CHAR si VARCHAR nu
mai constituie opiuni viabile pentru dumneavoastr.
Pentru coloanele ir pe care le vei folosi pentru a reprezenta un set fix de valori, putei lua n considerare
utilizarea unui tip de coloane ENUM sau SET. Acestea pot constitui opiuni utile, deoa.ece sunt reprezentate
intern sub form de numere. Operaiile cu aceste tipuri sunt efecoiate numeric, deci sunt mai eficiente dect alte
tipuri de iruri. De asemenea, pot fi mai compacte dect alte tipuri de coloane ir, ceea ce determin economii de
spaiu.
Cnd caracterizai domeniul de valori cu care trebuie s lucrai, termenii cei mai inspirai sunt ntotdeauna" si
niciodat" (de exemplu ntotdeauna mai mic dect 1000" sau niciodat negativ"), deoarece v ajut s
reducei mai mult opiunile privind tipurile de coloane. Dar pzii-v s folosii aceti termeni atunci cnd nu
sunt pe deplin justificai. Fii atent mai ales cnd v consultai cu alte persoane cu privire la datele lor si
respectivii ncep s v bombardeze cu aceti doi termeni. Cnd omul zice ntotdeauna" sau niciodat",
asigurai-v c vorbete serios. Uneori oamenii spun c datele lor au ntotdeauna o anumit caracteristic, pe
cnd n realitate vor s spun aproape ntotdeauna".
De exemplu, s presupunem c proiectai un tabel pentru anumite persoane si c acestea v spun: Rezultatele la
test sunt ntotdeauna cuprinse ntre O i 100." Bazndu-v pe aceast afirmaie, alegei tipul TINYINT i i dai
atributul UNSIGNED, deoarece valorile sunt ntotdeauna diferite de zero. Apoi, descoperii c persoanele care
codific datele pentru introducerea n baza de date folosesc uneori -l pentru a semnala c un elev a lipsit pe
motiv de boal. Mi s fie! P-asta nu v-au spus-o. Poate fi acceptabil s folosii NULL pentru a reprezenta
asemenea valori dar, dac nu se poate, va trebui s nregistrai un -l, dup care nu mai putei folosi o coloan
UNSIGNED. (Pas alergtor, direcia ALTER TABLE!)
Uneori, deciziile despre aceste tipuri de cazuri se pot lua mai uor punnd o ntrebare simpl: Exist vreodat
excepii? Dac se produce vreodat un caz excepional, chiar si o singur dat, trebuie s fii pregtit. Vei
descoperi c persoanele care discut cu dumneavoastr despre proiectarea unei baze de date sunt invariabil de
prere c, dac excepiile nu se produc foarte frecvent, atunci nu conteaz. Cnd creai un tabel, nu putei gndi
astfel, ntrebarea pe care trebuie s o punei nu este ct de frecvent se produc excepii, ci dac acestea se produc.
Dac excepiile se produc, trebuie s inei cont de ele.
Care sunt problemele de performan i de eficien?
Opiunea dumneavoastr privind tipul de coloane poate influena performanele interogrilor n numeroase
moduri. Dac avei n vedere ndrumrile generale discutate n seciunile anterioare, vei putea alege tipurile care
vor contribui la prelucrarea mai eficient n MySQL a datelor dumneavoastr.
140 Partea l Utilizarea general a sistemului MySQL Operaii numerice sau cu iruri
Operaiile numerice sunt, n general, mai rapide dect operaiile cu iruri. S ne gndim la operaiile de
comparaie. Numerele pot fi comparate dintr-o singur operaie. Comparaiile ntre iruri pot necesita mai multe
comparaii ntre octei, care sunt cu att mai multe cu ct irurile devin mai lungi.
Dac o coloan ir are un numr limitat de valori, folosii un tip ENUM sau TYPE, pentru a beneficia de
avantajele operaiilor cu numere. Aceste tipuri sunt reprezentate intern sub form de numere i pot fi prelucrate
mai eficient.
S ne gndim la reprezentrile alternative pentru iruri. Uneori, putei mbunti performanele prin
reprezentarea valorilor ir sub form de numere. De exemplu, pentru a reprezenta numerele IP n notaia cu
puncte, cum este 192.168.0.4, ai putea folosi un ir. Dar, ca alternativ, putei converti numerele IP n ntregi
prin stocarea fiecrei pri a formei cu puncte ntr-un octet din cei patru ai unui tip INT UNSIGNED. Astfel, se
va economisi spaiu i va creste viteza de cutare. Pe de alt parte, reprezentarea numerelor IP sub form de
valori I NT ar face dificil stabilirea de corespondene cu un model, cum sunt cele pe care le-ai face dac dorii
s cutai numere dintr-o subreea dat. Deci, nu putei ine cont numai de aspectele legate de spaiu; trebuie s
decidei reprezentarea cea mai adecvat n funcie de modul n care dorii s utilizai valorile.
Tipuri mai mari sau mai mici
Tipurile mai mici pot fi prelucrate mai rapid dect tipurile mai mari. Unul din motive ar fi acela c ocup spaiu
mai puin i implic o suprasarcin mai redus pentru activitatea discului. Pentru iruri, timpul de prelucrare se
afl ntr-o relaie direct cu lungimea irului.
n general, tabelele mai mici sunt mai rapide, deoarece prelucrarea interogrilor necesita mai puine operaii de
intrare-ieire cu discul. Pentru coloane care folosesc tipuri de dimensiune fix, alegei cel mai mic tip care va
conine domeniul impus de valori. De < exemplu, nu folosii BIGINT dac se poate utiliza MEDIUMINT. Nu
folosii DOUBLE dac] avei nevoie numai de o precizie FLOAT. Putei economisi spaiu chiar i n cazul
tipurilor de dimensiune variabil. Un BLOB folosete 2 octei pentru a nregistra lungimea valorii, un
LONGBLOB folosete 4 octei. Dac stocai valori care nu depesc niciodat 640KB> ] utilizarea tipului
BLOB v economisete 2 octei pentru fiecare valoare. (Consideraii si" milare sunt valabile i pentru tipurile
TEXT, desigur.)
Tipuri de lungime fix sau variabil
n general, tipurile de lungime fix pot fi prelucrate mai rapid dect tipurile de lungir variabil:
n cazul coloanelor de lungime variabil, un tabel n care se efectueaz numeroa actualizri sau tergeri va
prezenta un grad superior de fragmentare, datorit dime siunilor diferite a nregistrrilor. Va trebui s rulai
periodic procedura OPTIMI2 TABLE pentru conservarea performanelor. Aceasta nu constituie o problem n
caz* rndurilor de lungime fix.
Tabelele cu rnduri de lungime fix sunt mai uor de reconstruit n cazul cderii" unui tabel, deoarece poate fi
determinat nceputul fiecrei nregistrri. Acest lucru mi
Capitolul 2 Lucrul cu date n MySQL i SQL 141
este valabil la nregistrrile de lungime variabil i nu constituie o problem de performan n ceea ce privete
prelucrrile interogrilor, dar poate accelera n mod evident procesul de refacere a tabelului.
Dac n tabelul dumneavoastr exist coloane cu lungime variabil, conversia lor la coloane cu lungime fix va
determina o mbuntire a performanelor, deoarece nregistrrile cu lungime fix sunt mai uor de prelucrat,
nainte de a ncerca aceast operaie, inei cont de urmtoarele aspecte:
Utilizarea coloanelor cu lungime fix implic un compromis. Aceste coloane sunt mai rapide, dar ocup o
cantitate mai mare de spaiu. Coloanele CHAR (n) ocup ntotdeauna n octei pentru fiecare valoare (chiar i
pentru valorile vide), deoarece valorile sunt completate cu spaii finale atunci cnd sunt stocate n tabel.
Coloanele VARCHAR(n) ocup mai puin spaiu, deoarece este alocat numai spaiul necesar pentru stocarea
fiecrei valori, plus un octet n fiecare valoare pentru nregistrarea lungimii. Astfel, dac alegei ntre coloanele
CHAR i VARCHAR, se face un compromis ntre timp i spaiu. Dac viteza este problema dumneavoastr
principal, folosii coloanele CHAR pentru a obine avantajele de performan ale coloanelor de lungime fix.
Dac spaiul este la mare pre, folosii coloanele VARCHAR.
Nu putei converti o singur coloan de lungime variabil; trebuie s le convertii pe toate. De asemenea,
trebuie s convertii simultan toate coloanele de lungime variabil folosind o singur instruciune ALTER
TABLE; n caz contrar, demersul dumneavoastr nu va avea nici un efect.
Uneori, nu putei folosi un tip de coloan cu lungime fix, chiar dac dorii acest lucru. Nu exist tipuri de
lungime fix pentru iruri mai lungi de 255 caractere, de exemplu.
Tipuri indexabile
Indexurile mresc mult viteza interogrilor, deci alegei tipuri pe care le putei indexa. Vezi seciunea Aspecte
legate de indexare" pentru mai multe informaii.
Tipuri NULL sau NOT NULL
Dac declarai o coloan ca fiind NOT NULL, aceasta poate fi manipulat mai rapid, deoarece MySQL nu
trebuie s verifice valorile coloanelor n timpul prelucrrii interogrilor, pentru a vedea dac acestea conin sau
nu valoarea NULL. De asemenea, se economisete un bit pentru fiecare rnd din tabel.
Evitarea valorii NULL n coloane poate simplifica interogrile, deoarece nu trebuie s v mai gndii la NULL ca
la un caz special, n general, interogrile mai simple sunt prelucrate mai rapid.
ndrumrile legate de performan prezentate mai sus intr uneori n conflict. De exemplu, un rnd cu lungime
fix care conine coloane CHAR va fi mai rapid dect un rnd cu lungime variabil care conine coloane
VARCHAR, din punctul de vedere al capacitii sistemului MySQL de localizare a rndurilor. Pe de alt parte,
un asemenea rnd va ocupa mai mult spaiu, deci implic o activitate suplimentar a discului. Din acest punct de
vedere, VARCHAR poate fi mai rapid. Ca regul empiric, putei presupune c rndurile cu lungime fix vor
determina o cretere a performanelor, chiar dac se folosete o cantitate mai mare de spaiu. Pentru o aplicaie
deosebit de important, putei implementa
142 Partea l Utilizarea general a sistemului MySQL
un tabel n ambele moduri i eventual efectuai teste pentru a determina alternativa cea mai bun pentru aplicaia
respectiv.
Cum dorii s fie comparate valorile dumneavoastr?
Putei determina compararea i sortarea tipurilor ir ntr-un mod sensibil sau nu la diferena ntre majuscule si
minuscule prin modul n care declarau aceste tipuri. Tabelul 2.14 prezint fiecare tip care nu este sensibil la
diferena ntre majuscule i minuscule, precum i echivalentul su sensibil la o atare diferen. Unele tipuri
(CHAR, VARCHAR) sunt binare sau nu n funcie de prezena sau absena cuvntului cheie BINARY n
declaraia coloanei. Caracterul binar al altor tipuri (BLOB, TEXT) este coninut implicit n numele tipului.
Tabelul 2.14 Sensibilitatea tipurilor ir la diferena ntre majuscule si minuscule
Tip non-binar (insensibil la diferena ntre majuscule i minuscule)
CHAR(M)
VARCHAR(W)
TINYTEXT
TEXT
MEDIUMTEXT
LONGTEXT
Tip binar (sensibil la diferena ntre majuscule i minuscule)
CHAR(M) BINARY
VARCHAR(M) BINARY
TINYBLOB
BLOB
MEDIUMBLOB
LONGBLOB
Reinei c tipurile binare (sensibile la diferena ntre majuscule si minuscule) difer de omoloagele lor non-
binare (insensibile la diferena ntre majuscule i minuscule) numai n ceea ce privete comportarea n materie de
comparare i sortare. Orice tip ir poate conine orice categorie de date. n particular, tipurile TEXT pot conine
date binare fr nici un fel de probleme, n ciuda meniunii TEXT" din numele tipurilor de coloane.
Dac dorii s folosii o coloan att pentru comparaii sensibile la diferena ntre majusr l cule i minuscule, ct
i pentru comparaii insensibile la o asemenea diferen, folosii un l tip non-binar. Apoi, de fiecare dat cnd
dorii o comparaie sensibil la diferena ntre i majuscule i minuscule, folosii cuvntul cheie BINARY pentru a
fora tratarea unui ir c pe o valoare de tip ir binar. De exemplu, n cazul n care coloanajnea este o coloana l
CHAR, o putei compara n moduri diferite:
coloanajnea = "ABC" Insensibil la diferena ntre majuscule i
BINARY coloanajnea = "ABC" Sensibil la diferena ntre majuscule i minuscule >|

coloanajnea = BINARY "ABC" Sensibil la diferena ntre majuscule si minuscule "|


Dac avei valori ir pe care dorii s le sortai ntr-o anumit ordine ne-lexicografic avei n vedere utilizarea
unei coloane ENUM. Sortarea valorilor ENUM se produce n con4 formitate cu ordinea n care menionai
valorile din enumerare n declaraia coloanei}l deci putei determina sortarea acestor valori n orice ordine dorii.
Capitolul 2 Lucrul cu date n MySQL si SQL 143
Intenionai s indexai o coloan?
Indexurile permit sistemului MySQL s prelucreze interogrile mai rapid. Alegerea indexurilor este o problem
discutat mai detaliat n capitolul 4, dar un principiu general precizeaz c acele coloane pe care le folosii de
obicei n clauzele WHERE pentru selectarea rndurilor constituie cele mai bune opiuni pentru indexare.
Dac dorii s indexai o coloan sau s o includei ntr-un index cu mai multe coloane, exist restricii privind
tipurile pe care le putei alege, n versiunile MySQL anterioare versiunii 3.23.2, coloanele indexate trebuie
declarate NOT NULL, dup cum tipurile BLOB si TEXT nu pot fi indexate. Aceste restricii au fost eliminate n
MySQL 3.23.2, dar, dac folosii o versiune anterioar i nu putei sau nu dorii s trecei la o versiune mai
recent, trebuie s lucrai cu aceste restricii. Totui, putei ocoli restriciile n urmtoarele situaii:
Dac putei specifica o anumit valoare ca fiind special, o putei trata ca si cum ar avea aceeai semnificaie ca
i NULL. Pentru o coloan DATE, putei desemna valoarea "0000-00-00" ca avnd semnificaia fr dat", ntr-
o coloan de tip ir, putei preciza c un ir vid are semnificaia valoare lips", ntr-o coloan numeric, putei
folosi -l dac, n mod normal, coloana va conine numai valori non-negative.
Nu putei indexa tipurile BLOB sau TEXT, dar, dac irurile dumneavoastr nu depesc 255 de caractere,
folosii tipul de coloan echivalent VARCHAR si indexai-l pe acela. Putei folosi VARCHAR (255) BINARY
pentru valorile BLOB, respectiv VARCHAR (255) pentru valorile TEXT.
Intercorelarea problemelor legate de selectarea tipului de coloan
Nu putei lua ntotdeauna n considerare problemele legate de selectarea tipurilor de coloane ca i cum acestea ar
fi independente una de alta. De exemplu, n cazul tipurilor numerice domeniul este corelat cu dimensiunea
spaiului de stocare; cnd domeniul creste, avei nevoie de o cantitate mai mare de spaiu, ceea ce afecteaz
performanele. Ca alt exemplu, luai n considerare implicaiile opiunii de utilizare a atributului
AUTO_INCREMENT pentru crearea unei coloane care s conin numere de secven unice. Opiunea
respectiv are numeroase consecine, care implic tipul coloanei, indexarea i utilizarea valorii NULL:
AUTO_INCREMENT este un atribut de coloan care trebuie folosit numai cu tipuri ntregi. Astfel, opiunile
dumneavoastr sunt imediat limitate la tipurile cuprinse ntre TINYINTiBIGINT.
Coloanele AUTO_INCREMENT trebuie indexate de aa manier nct numrul curent maxim din cadrul
secvenei s poat fi determinat rapid, fr a necesita o parcurgere complet a tabelului, n continuare, pentru a
preveni reutilizarea numerelor din secven, indexul trebuie s fie unic. Aceasta nseamn c trebuie s declarai
coloana ca PRIMARY KEY sau ca index de tip UNIQUE.
Dac versiunea dumneavoastr de MySQL este anterioar versiunii 3.23.2, coloanele indexate nu pot conine
valori NULL, deci trebuie s declarai coloana ca fiind de tip NOT
NULL.
144 Partea l Utilizarea general a sistemului MySQL
Toate acestea nseamn c nu putei declara o coloan AUTO_INCREMENT astfel:
col tip_arbitrar AUTO_INCREMENT O astfel de coloan se declar dup cum urmeaz:
col tip_intreg AUTO_INCREMENT NOT NULL PRIMARY KEY Sau astfel:
col tip_intreg AUTO_INCREMENT NOT NULL, UNIQUE(col)
O consecin suplimentar a utilizrii atributului AUTO_INCREMENT este aceea c, atributul fiind destinat
generrii unei secvene de valori pozitive, putei la fel de bine s declarai o coloan AUTO_INCREMENT ca
fiind UNSIGNED:
col tip_intreg UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY
col tip_intreg UNSIGNED AUTO_INCREMENT NOT NULL, UNIQUE(col)
Evaluarea expresiilor i conversia de tip
MySQL v permite s scriei expresii care includ constante, apeluri la funcii si referine j la coloane dintr-un
tabel. Aceste valori pot fi combinate folosind diferite categorii de operatori, precum operatorii aritmetici sau de
comparaie, iar termenii unei expresii pot j fi grupai cu ajutorul parantezelor.
Expresiile apar cel mai frecvent n lista de selecie a coloanei i n clauza WHERE a j instruciunilor SELECT:
SELECT
CONCAT(nume, ", ", prenume),
(TO_DAYS(data_deces) - TO_DAYS(data_nastere) / 365) FROM preedinte WHERE
data_nastere > "1900-1-1" AND data_deces IS NOT NULL Fiecare coloan selectat reprezint o expresie, ca i
coninutul clauzei WHERE. De asemenea,! expresiile mai apar n clauza WHERE a instruciunilor DELETE si
UPDATE, n clauza VALUES () instruciunilor INSERT si aa mai departe.
Cnd MySQL ntlnete o expresie, o evalueaz pentru a calcula un rezultat. De exemplu (4*3) / (4-2) are
rezultatul 6. Evaluarea expresiilor poate necesita conversii de tijk De exemplu, MySQL convertete numrul
960821 ntr-o dat, i anume "1996-08-2v atunci cnd numrul este folosit ntr-un context care necesit o valoare
de tip dat.
Aceast seciune discut modul n care putei scrie expresii n MySQL, precum i sunt regulile care guverneaz
diferitele categorii de conversii de tip pe care le execul MySQL n decursul procesului de evaluare a expresiilor.
Fiecare dintre operator MySQL este prezentat aici, dar MySQL are un numr att de mare de funcii, nct vot
aborda numai cteva. Totui, fiecare operator i fiecare funcie sunt prezentate n det n Anexa C.
Capitolul 2 Lucrul cu date n MySQL i SQL 145
Scrierea expresiilor
O expresie se poate reduce la o singur constant: O Constant numeric
" abc" Constant de tip ir
Expresiile folosesc apeluri la funcii. Unele funcii iau argumente (valori plasate ntre paranteze), altele nu.
Argumentele multiple trebuie s fie separate prin virgul. Cnd invocai o funcie, argumentele pot fi delimitate
prin spaii, dar ntre numele funciei si paranteza de deschidere nu trebuie s existe nici un spaiu:
NOW() Funcie fr argumente
STRCMP (" abc"," def") Funcie cu dou argumente
STRCMP( "abc", "def ) Sunt permise spatiile n jurul argumentelor
STRCMP (" abc"," def") Spaiile plasate dup numele funciei sunt
interzise
Dac exist un spaiu dup numele funciei, analizorul MySQL poate interpreta numele funciei ca pe un nume
de coloan. (Numele funciilor nu sunt cuvinte rezervate i le putei folosi pentru nume de coloan, dac dorii.)
Rezultatul obinuit este o eroare de sintax.
n expresii se pot folosi si valori din coloanele tabelelor, n situaia cea mai simpl, cnd tabelul cruia i aparine
o coloan rezult evident din context, o referin de coloan se poate rezuma, pur si simplu, la numele coloanei,
n fiecare din urmtoarele instruciuni SELECT este specificat un singur tabel; astfel, referinele la coloane sunt
lipsite de echivoc:
SELECT nume, prenume FROM preedinte
SELECT nume, prenume FROM membru
Dac nu este clar identitatea tabelului care va fi folosit, numele coloanelor pot fi precedate de numele tabelului.
Dac nu este clar nici mcar numele bazei de date care trebuie folosit, numele tabelului poate fi precedat de
numele bazei de date. De asemenea, putei folosi aceste forme mai concrete n contexte lipsite de echivoc, dac
dorii pur i simplu s fii mai explicit:
SELECT
preedinte.nume, preedinte.prenume, membru.nume, membru.prenume
FROM preedinte, membru
WHERE preedinte.nume = membru.nume
SELECT samp_db.elev.nume FROM samp_db.elev n final, putei combina toate aceste tipuri de valori pentru a
forma expresii mai complexe.
Tipuri de operatori
MySQL include numeroase tipuri de operatori care pot fi folosii pentru a combina termenii expresiilor.
Operatorii aritmetici, prezentai n tabelul 2.15, includ operatorii obinuii de adunare, scdere, nmulire i
mprire, precum i operatorul modulo. Operaiile aritmetice se execut folosind valori ntregi BIGI NT (de 64
bii) pentru opera-
146 Partea l Utilizarea general a sistemului MySQL
torii -, - si * atunci cnd ambii operanzi sunt ntregi, precum i pentru operatorii / i % l atunci cnd operaia
este efectuat ntr-un context unde se ateapt ca rezultatul s fie un! ntreg. Reinei ca, dac o operaie implic
valori mari, astfel nct rezultatul depete J domeniul pe 64 de bii, vei obine rezultate imprevizibile.
Tabelul 2.15 Operatori aritmetici
Operator
Sintax
a b
a - b -a
a* b
a/ b
a% b
Semnificaie
Adunare; suma operanzilor
Scdere; diferena ntre operanzi
Minus unar negaia operandului
nmulire; produsul operanzilor
mprire; catul operanzilor
Modulo; restul rmas dup mprirea operanzilor
Operatorii logici, prezentai n tabelul 2.16, evalueaz expresii pentru a determina da sunt adevrate (diferite de
zero) sau false (zero). MySQL include operatorii n stil C" &&J 11 i ! ca forme alternative pentru AND, OR i
NOT. Observai mai ales operatorul 11; ANS|j SQL specific 11 ca operator de concatenare a irurilor, dar n
MySQL are semnificaia unei operaii OR (SAU) logice. Dac executai urmtoarea interogare i v ateptai
aceasta s execute concatenarea irurilor, veri descoperi cu surprindere c returne numrul 0:
SELECT "abc" || "def" <> O
" abc" si " def" sunt convertite n ntregi n vederea operaiei, iar ambele se transform n 0. n MySQL, trebuie
s folosii funcia CONCAT( "abc", "def") pentru a efectua concatenarea irurilor.
Tabelul 2.16 Operatori logici
Operator
AND, && OR, || NOT, !
Sintax
a AND b, a && b
a OR b, a || b NOT a, la
Semnificaie
Intersecie logic; adevrat dac ambii operanzi sunt adevrai
Reuniune logic; adevrat dac oricare din operanzi este adevrat
Negare logic; adevrat dac operandul este fals
Operatorii pe bit, prezentai n tabelul 2.17, execut intersecii i reuniuni la nivel de l unde fiecare bit al
rezultatului este evaluat sub forma interseciei sau reuniunii logicdf biilor corespunztori ai operanzilor. De
asemenea, putei executa deplasri ale biilor'l| stnga sau la dreapta. Operaiile cu bii sunt efectuate folosindu-
se valori ntregi BIGIf (pe 64 de bii).
Capitolul 2 Lucrul cu date n MySQL i SQL 147
Tabelul 2.17 Operatori pe bit
Operator Sintax
& a&b
ab
ab
Semnificaie
Intersecie (AND) la nivel de bit; fiecare bit al rezultatului este setat dac biii corespunztori ai ambilor operanzi
sunt setai
Reuniune (OR) la nivel de bit; fiecare bit al rezultatului este setat dac bitul corespunztor al oricruia dintre
operanzi este setat
Deplasare la stnga a lui a cu b poziii de bit Deplasare la dreapta a lui a cu b poziii de bit
Operatorii de comparaie, prezentai n tabelul 2.18, includ operatori pentru testarea mrimii relative sau a
aranjrii lexicografice a numerelor i a irurilor, precum i operatori pentru stabilirea corespondenei cu un
model si pentru detectarea valorilor NULL. Operatorul <=> este specific limbajului MySQL i a fost introdus n
MySQL 3.23.
Tabelul 2.18 Operatori de comparaie
Operator
IN
BETWEEN
LIKE
NOT LIKE REGEXP
Sintax
a =b
a != b, a <> b
a <b
a <= b
a >= b
a >b
a IN (b1, b2, ...
a BETWEEN b AND C
a LIKE b
a NOT LIKE b
a REGEXP b
NOT REGEXP a NOT REGEXP b
IS NULL
IS NOT NULL
a <=> b
a IS NULL
a IS NOT NULL
Semnificaie
Adevrat dac operanzii sunt egali Adevrat dac operanzii sunt diferii Adevrat dac a este mai mic dect b
Adevrat dac a este mai mic sau egal cu b Adevrat dac a este mai mare sau egal cu b Adevrat dac a este mai
mare dect b ) Adevrat dac a este egal cu oricare din termenii bl, b2,... Adevrat dac a se afl ntre valorile
lui b si c, inclusiv b i c
Coresponden cu modelul n SQL; adevrat dac a corespunde cu b
Coresponden cu modelul n SQL; adevrat dac a
nu corespunde cu b
Coresponden cu o expresie regulat extins; adevrat
dac a corespunde cu b
Coresponden cu o expresie regulat extins; adevrat
dac a nu corespunde cu b
Adevrat dac operanzii sunt egali (chiar dac au valoarea NULL)
Adevrat dac operandul este NULL Adevrat dac operandul nu este NULL
Operatorul BINARY este disponibil ncepnd cu MySQL versiunea 3.23 si poate fi folosit pentru conversia unui
ir ntr-un ir binar, astfel nct s fie sensibil la diferena ntre
148 Partea l Utilizarea general a sistemului MySQL
majuscule i minuscule n cazul comparaiilor. Prima dintre urmtoarele comparaii mi' este sensibil la diferena
ntre majuscule si minuscule, dar a doua si a treia sunt:
"abc" = "Abc" 1
BINARY "abc" = "Abc" O
"abc" = BINARY "Abc" O
Nu exist nici o conversie corespunztoare NOT BINARY. Dac dorii s folosii o coloana att ntr-un context
sensibil la diferena ntre majuscule i minuscule, ct si ntr-un context fr aceast caracteristic, folosii un tip
de coloan care nu este sensibil la diferenat ntre majuscule i minuscule i utilizai BINARY pentru acele
comparaii pe care le dorii^ sensibile la diferena ntre majuscule i minuscule.
Comparaiile sunt ntotdeauna sensibile la diferena ntre majuscule i minuscule pentru, coloanele pe care le
declarai folosind un tip de ir binar (CHAR BINARY, VARCHAR BINARY' i tipurile BLOB). Pentru a obine
o comparaie care nu este sensibil la diferena ntre majuscule si minuscule pentru un asemenea tip de coloan,
folosii UPPER () sau LOWER ()' pentru a converti ambii operanzi la aceeai mrime a literei:
UPPER(nume_coloana) < UPPER("lonescu") '
LOWER(nume_coloana) < LOWER("lonescu') ]13
Pentru comparaii ntre iruri care nu sunt sensibile la diferena ntre majuscule ; minuscule, este posibil ca mai
multe caractere s fie considerate echivalente, n funcii de setul dumneavoastr de caractere. De exemplu, E si E
s-ar putea s fie tratate identi( n cadrul operaiilor de comparaie i ordonare. Comparaiile binare (sensibile la
difer renta ntre majuscule si minuscule) se execut folosind valorile ASCII ale caracterelor.
Corespondena cu un model v ajut s cutai valori fr a fi obligat s specificai o valoari literal exact.
MySQL furnizeaz corespondena cu un model din SQL folosind operato-] nil LIKE i caracterele de nlocuire
% (corespunde oricrei secvene de caractere) si _ (cores-i punde oricrui caracter individual). De asemenea,
MySQL furnizeaz corespondena cu model bazndu-se pe operatorul REGEXP i pe expresiile regulate extinse
care sunt simil; celor folosite n programele UNIX precum grep, ed si vi. Trebuie s folosii unul dim aceti
operatori de stabilire a corespondenelor cu un model pentru a efectua stabili corespondenei cu un model; nu
putei folosi operatorul =. Pentru a inversa sensul uni operaii de stabilire a corespondenei cu un model, folosii
NOT LIKE sau NOT REGEXP.
Cele dou tipuri de stabilire a corespondenei cu un model difer sub dou aspecte import tante, dincolo de
utilizarea unor operatori diferii i a unor caractere de model diferite:.,
LIKE nu este sensibil la diferena ntre majuscule si minuscule dect dac minimum operand este un ir binar.
REGEXP este sensibil la diferena ntre majuscule si minuscule1*
Modelele SQL corespund cu valoarea gsit numai dac ntregul ir corespunde Expresiile regulate corespund
dac modelul este gsit oriunde n interiorul irului.
10 ncepnd de la versiunea 3.23.4, REGEXP nu mai este sensibil la diferena ntre majuscule i mimi cule dect
dac minimum un operand este un ir binar. - N.A.
Capitolul 2 Lucrul cu date n MySQL i SQL 149
Modelele folosite cu operatorul LIKE pot include caracterele de nlocuire % i _. De exemplu, modelul "ele%"
corespunde tuturor irurilor care ncep cu "ele":
"elevat" LIKE "ele%" * 1
"elementar" LIKE "ele%" * 1
Caracterul de nlocuire % corespunde oricrei secvene de caractere, inclusiv cu secvena vid, deci "ele%"
corespunde lui "ele":
"ele" LIKE "ele%" t> 1
Aceasta mai nseamn c modelul "%" corespunde oricrui ir, inclusiv irului vid. Totui, "V nu va corespunde
valorii NULL. De fapt, orice stabilire de coresponden cu un model care conine un operand NULL va eua:
"ele" LIKE NULL O NULL
NULL LIKE "ele%" * NULL
Operatorul LIKE din MySQL nu este sensibil la diferena ntre majuscule i minuscule, dect dac unul din
operanzii si este un ir binar. Astfel, "ele%" este echivalent n mod prestabilit att cu irul "elevat" ct i cu irul
"Elevat", dar ntr-o comparaie binar va fi echivalent numai cu unul din cele dou iruri:
"Elevat" LIKE "ele%" *1
"elevat" LIKE "ele%" o1
BINARY "elevat" LIKE "ele%" o1
BINARY "Elevat" LIKE "eleV <* O
Acest lucru nu se ntmpl n cazul operatorului LIKE din ANSI SQL, care este sensibil la diferena ntre
majuscule i minuscule.
Caracterul de nlocuire poate fi specificat oriunde n interiorul modelului. De exemplu, "%at" este echivalent cu
"birocrat", "colorat" sau "aristocrat". Pe de alt parte, "%at%" este echivalent cu toate irurile de mai sus, dar si
cu iruri gen "crater", "atent" sau "straturi".
Cellalt caracter de nlocuire permis pentru LIKE este _, care corespunde oricrui caracter
individual.___corespunde oricrui ir format din exact trei caractere, "a_r" corespunde cu "aer" i "aur" i chiar
cu "a_r", deoarece _ este echivalent cu el nsui.
Pentru a dezactiva semnificaia special a caracterelor de nlocuire % si _, pentru a corespunde instanelor
literale ale acestor caractere, precedai-le cu un backslash (\% sau \_):
"abc" LIKE "a%c" <* 1
"abc" LIKE "a\%c" ^O
"a%c" LIKE "a\%c" <* 1
Cealalt form folosit n MySQL pentru stabilirea corespondenelor cu un model folosete expresiile regulate.
Operatorul este REGEXP, nu LIKE. (RLIKE este un sinonim pentru REGEXP.) Caracterele de model cele mai
folosite n cazul expresiilor regulate sunt urmtoarele:
corespunde oricrui caracter individual:
"abc" REGEXP "a.c" o 1

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