MySql este una dintre cele mai folosite baze de date Open Source. A fost gandita pentru web si este folosita cu succes pentru a scala. Google, Wikipedia, Facebook, Amazon, Flickr si multi altii o folosesc. Dintre subiectele pe care le vom atinge: tipuri de tabele, indecsi, foreign key-uri, subquery-uri, tabele temporare, triggere, view-uri, join-uri, notiuni de proceduri stocate si multe altele. La fiecare pas voi prezenta exemple pentru a demonstra facilitatile prezentate.
2. Noţiuni avansate MySQL
Noţiuni avansate MySQL
• MySQL • Views
• Arhitectura MySQL • Comenzi sql avansate
• Tabele • Join-uri
• Tipuri de date • DESCRIBE
• Indecşi • Slow query log
• Foreign key-uri • Query cache
• Triggere • Performanţă
• Proceduri stocate
Mihai Oaida <mihai.oaida@gmail.com> 01
3. Noţiuni avansate MySQL
MySQL
3.23 - vechi
4.1x - stabil, puţine funcţionalităţi
5.0x - GA
5.1 - GA
5.4 - RC
6.x - ?
Mihai Oaida <mihai.oaida@gmail.com> 02
5. Noţiuni avansate MySQL
Tabele
Tipuri de tabele
• MyISAM
• InnoDB
• Memory / HEAP
• MERGE, MRG_MyISAM
• Black hole
• CSV
• ARCHIVE
CREATE TABLE t( columns) ENGINE =
sau
ALTER TABLE t ENGINE =
Mihai Oaida <mihai.oaida@gmail.com> 04
6. Noţiuni avansate MySQL
Tipuri de date - int
TINYINT 1byte
SMALLINT 2Bytes
MEDIUMINT 3 bytes
INT 4bytes
-2147483648 +2147483647
BIGINT 8 bytes
Probleme comune
INT(4) – ZEROFILL – ex 0001
Mihai Oaida <mihai.oaida@gmail.com> 05
7. Noţiuni avansate MySQL
Tipuri de date – dată şi timp
DATETIME 2009-07-09 21:15:15
DATE 2009-07-09
TIMESTAMP la fel ca DATE dar în raza timestamp
de la 1 ian 1970 până în 2038
TIME 21:15:15
Mihai Oaida <mihai.oaida@gmail.com> 06
8. Noţiuni avansate MySQL
Tipuri de date – şir
CHAR - consumă spatiu fix
VARCHAR - consumă spatiu în funcţie de lungime
• 0-255 caractere
• coloane cu encoding
BINARY
VARBINARY
• date binare
TINYBLOB TINYTEXT
BLOB TEXT
MEDIUMBLOB MEDIUMTEXT
LONGBLOB LONGTEXT
Mihai Oaida <mihai.oaida@gmail.com> 07
9. Noţiuni avansate MySQL
Tipuri de date – ENUM şi SET
Atunci când lista de valori este fixă
Consumă puţin spaţiu
CREATE TABLE oameni{
id TINYINT PRIMARY KEY autoincrement,
nume VARCHAR(25),
sex ENUM('masculin','feminin')
}
INSERT INTO oameni(nume,sex) VALUES('Ion
Popescu','masculin');
CREATE TABLE newsletter{
id TINYINT PRIMARY KEY autoincrement,
nume VARCHAR(25),
categorie SET('evenimente','stiri','sport')
}
INSERT INTO newsletter(nume,categorie) VALUES('Ion
Popescu','stiri,sport');
Mihai Oaida <mihai.oaida@gmail.com> 08
10. Noţiuni avansate MySQL
Indecşi
• Ordonăm tabelul dupa 1 sau n coloane
• Tipuri de indecşi
PRIMARY KEY
Index
Unique
Full Text
• Tipuri de algoritmi : BTREE si HASH
• Aplicate pe 1 sau mai multe coloane (multiple index)
CREATE INDEX i_name ON table_name(col1,col2,..)
Mihai Oaida <mihai.oaida@gmail.com> 09
11. Noţiuni avansate MySQL
Full text index
Căutare în texte
SELECT id,titlu FROM table WHERE
MATCH(titlu) AGAINST(‘xml’)
SELECT id,titlu FROM table WHERE
MATCH(titlu) AGAINST(‘xml’ WITH QUERY
EXPANSION)
Mihai Oaida <mihai.oaida@gmail.com> 10
12. Noţiuni avansate MySQL
Foreign key
Formează legăturile între tabele.
Legături care la proiectare le formăm prin convenţie.
Exemplu : news.cat_id – cat.id
Exemplu : InnoDB
Se pot adăuga la crearea tabelului sau ulterior
FOREIGN KEY(cat_id) REFERENCES cat(id)
Mihai Oaida <mihai.oaida@gmail.com> 11
13. Noţiuni avansate MySQL
Triggere
Obiect asociat unui tabel care se apelează la un
anumit eveniment
CREATE TRIGGER trig_name {BEFORE| AFTER}
{INSERT,REPLACE,UPDATE, DELETE} on t
FOR EACH ROW BEGIN
..sql..
END;
Mihai Oaida <mihai.oaida@gmail.com> 12
14. Noţiuni avansate MySQL
Exemplu
CREATE TRIGGER updateCateg AFTER INSERT ON
produse
FOR EACH ROW BEGIN
UPDATE cats SET nr=nr+1 WHERE
id=NEW.cat_id;
END;
Mihai Oaida <mihai.oaida@gmail.com> 13
15. Noţiuni avansate MySQL
Views
CREATE VIEW view_name AS [query]
DROP VIEW view_name
CREATE VIEW stats_l AS SELECT l.id,l.nume, ( SELECT
count( c.id ) FROM comentarii c WHERE c.lectie_id =
l.id ) AS nr_comentarii , ( SELECT count( r.id )
FROM rezolvari r WHERE r.lectie_id = l.id ) AS
nr_rezolvari FROM lectii l ORDER BY id ASC
SELECT * FROM stats_l
Mihai Oaida <mihai.oaida@gmail.com> 14
16. Noţiuni avansate MySQL
Proceduri stocate
Subrutine care se reţin în baza de date
Folosite pentru
• A testa datele
• A muta sql din logica aplicaţiei în db
• A minimiza traficul dintre client şi db
Mihai Oaida <mihai.oaida@gmail.com> 15
17. Noţiuni avansate MySQL
Exemplu
delimiter //
DROP PROCEDURE IF EXISTS colavg//
CREATE PROCEDURE colavg(IN tbl CHAR(64),IN col
CHAR(64))
READS SQL DATA
COMMENT 'Selects the avg of column col in table tbl'
BEGIN SET @s = CONCAT('SELECT AVG(' , col , ') FROM
' , tbl);
PREPARE stmt FROM @s;
EXECUTE stmt;
END;
//
delimiter ;
CALL colavg('t_note','nota');
Mihai Oaida <mihai.oaida@gmail.com> 16
18. Noţiuni avansate MySQL
GROUP BY
SELECT cat_id,count(id) FROM posts GROUP BY id
Numărul de post-uri din fiecare categorie.
Mihai Oaida <mihai.oaida@gmail.com> 17
19. Noţiuni avansate MySQL
HAVING
SELECT cat_id,count(id) FROM posts GROUP
BY id HAVING count(id)<=100
Numărul de post-uri din fiecare categorie care are mai
puţin de 100 de elemente
Mihai Oaida <mihai.oaida@gmail.com> 18
20. Noţiuni avansate MySQL
SubQuery-uri
SELECT count(sum) FROM (SELECT nr AS sum FROM
cats WHERE cat_id=3);
SELECT lectii.nume,(SELECT count(id) FROM
rezolvari WHERE lectii.id=rezolvari.lectie_id)
AS nr FROM lectii;
Mihai Oaida <mihai.oaida@gmail.com> 19
21. Noţiuni avansate MySQL
JOIN-uri
Join - produs cardinal între 2 tabele
- condiţie de join
SELECT camp1,camp2,.. FROM t1
[tip-join] t2 ON conditii [tip-join] t3
ON conditii … [WHERE conditii]
INNER JOIN
coloanele din stănga şi dreapta se adaugă dacă ambele
respectă condiţia
LEFT JOIN
coloana stângă se adaugă şi dreapta numai dacă respectă
condiţia
RIGHT JOIN
coloana dreaptă se adaugă şi stânga numai dacă respectă
condiţia
Mihai Oaida <mihai.oaida@gmail.com> 20
22. Noţiuni avansate MySQL
Exemple – INNER JOIN
SELECT elevi.id,comentarii.comentariu FROM
elevi INNER JOIN comentarii ON
elevi.id=comentarii.elev_id
SELECT elevi.id,comentarii.comentariu FROM
elevi , comentarii WHERE
elevi.id=comentarii.elev_id
SELECT e.id,c.comentariu FROM
elevi e INNER JOIN comentarii c
ON e.id=c.elev_id
Mihai Oaida <mihai.oaida@gmail.com> 21
23. Noţiuni avansate MySQL
LEFT JOIN
SELECT e.username,c.comentariu FROM
elevi e LEFT JOIN comentarii c
ON e.id=c.elev_id
Selectează toţi elevii pe coloana din stânga şi
pe cea din dreapta comentarii, dacă există
Mihai Oaida <mihai.oaida@gmail.com> 22
24. Noţiuni avansate MySQL
RIGHT Join
SELECT e.username,c.comentariu FROM
elevi e LEFT JOIN comentarii c
ON e.id=c.elev_id
• Opusul lui LEFT JOIN
• Selectează toate comentariile în coloana din
dreapta şi pe coloana din stângă username-ul
daca relaţia este satisfăcută.
• Daca nu se afişează NULL
Mihai Oaida <mihai.oaida@gmail.com> 23
25. Noţiuni avansate MySQL
DESCRIBE
• Arată planul de execuţie ales de optimizator
• Arată pentru fiecare tabel din sql : indecşi
folosiţi, tipul căutării, numărul de rânduri prin
care caută, etc
• DESCRIBE [sql]
• Câmpuri
Select_type – tip qurery
Table – nume tabel
Possible_keys – key-uri luate în considerare
Key – cheia aleasă
Key_len – lungimea
Rows – nr. aprox. de rânduri prin care caută
Extra – file sort, tmp table, etc
Mihai Oaida <mihai.oaida@gmail.com> 24
26. Noţiuni avansate MySQL
Slow query log
Locaţie my.ini
log_slow_queries = /var/log/mysql/my-slow.log
long_query_time = 2
log-queries-not-using-indexes
Mihai Oaida <mihai.oaida@gmail.com> 25
27. Noţiuni avansate MySQL
Query cache
Locaţie my.ini
query_cache_limit = 64M
query_cache_size = 64M
Nu trebuie setată prea mare
Raportul read/write – invalidarea cache-ului
Trebuie urmărit cache hits
Mihai Oaida <mihai.oaida@gmail.com> 26
28. Noţiuni avansate MySQL
Performanţă
• Datele reţinute pe tipul cel mai mic
md5 hash – binary(16) pack()
ip – int 4 bytes ip2long()
• Indecşi mici – mai multă informaţie încape
într-un bloc de memorie
• Indecşi pe cheia de join
• Binary log off
Don’t
SELECT * FROM table ORDER BY RAND() LIMIT 1
SELECT COUNT(*) FROM table
SELECT DISTINCT column FROM table
Mihai Oaida <mihai.oaida@gmail.com> 27
29. Noţiuni avansate MySQL
Referinţe
RTFM
http://dev.mysql.com/doc/refman/5.0/en/
http://dev.mysql.com/doc/refman/5.1/en/
http://dev.mysql.com/tech-resources/articles/
Scule
http://dev.mysql.com/workbench/
http://dev.mysql.com/downloads/gui-tools/5.0.html
http://munin.projects.linpro.no/
Lectură
http://www.mysqlperformanceblog.com/
Mihai Oaida <mihai.oaida@gmail.com> 28