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 ●
Vizualizări
●
Arhitectura MySQL (Views)
●
Tabele
●
Descrierea comenzilor
(DESCRIBE )
●
Tipuri de date ●
Jurnal de interogări lente
●
Indecşi (Slow query log)
●
Partiționare ●
Cache de interogări
●
Declanșatoare (Query cache)
(Triggers) ●
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 - Beta
6.x - ?
Mihai Oaida <mihai.oaida@gmail.com> 02
4. Noţiuni avansate MySQL
Arhitectura MySQL
http://dev.mysql.com/doc/refman/5.1-maria/en/images/PSEArch.png
Mihai Oaida <mihai.oaida@gmail.com> 03
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ă spațiu fix
VARCHAR - consumă spațiu î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 AUTO_INCREMENT,
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 după una sau mai multe
coloane (multiple index)
• Tipuri de indecşi
- PRIMARY KEY
- Index
- Unique
- Full Text
• Tipuri de algoritmi : BTREE sau HASH
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
●
Returnează rezultatele în ordinea relevanței
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
Partiționare
• Opțiune de creare a tabelelor
• Distribuie tabel pe mai multe partiții după
valorile unei coloane sau a unei expresii
• Trasparent pentru utilizator
• Crește viteza de execuție a interogărilor
• Nu are suport pentru chei străine
• Suportă maxim 1024 de partiții pentru un tabel
• MySQL 5.1
Opțiuni de partiționare
– RANGE valorile se încadrează în anumite intervale
– LIST valorile se încadrează într-o listă de valori
– HASH după o funcție specificată de utilizator
– KEY similar cu HASH, funcția este furnizată de server
* pentru HASH și KEY se specifică numărul de partiții
Mihai Oaida <mihai.oaida@gmail.com> 11
13. Noţiuni avansate MySQL
Partiționare – exemplu 1
CREATE TABLE users(
id MEDIUMINT AUTO_INCREMENT,
username VARCHAR(50),
passsword CHAR(32),
email VARCHAR(50),
PRIMARY KEY (id)
)ENGINE=MyISAM
PARTITION BY RANGE(id)(
PARTITION p0 VALUES LESS THAN (1000),
PARTITION p1 VALUES LESS THAN (2000),
PARTITION p2 VALUES LESS THAN MAXVALUE
)
Mihai Oaida <mihai.oaida@gmail.com> 12
14. Noţiuni avansate MySQL
Partiționare – exemplu 2
CREATE TABLE users(
id INT AUTO_INCREMENT,
username VARCHAR(50),
passsword CHAR(32),
email VARCHAR(50),
PRIMARY KEY (id)
)ENGINE=MyISAM
PARTITION BY KEY(id)
PARTITIONS 10
Mihai Oaida <mihai.oaida@gmail.com> 13
15. Noţiuni avansate MySQL
Trigger
Cod sql asociat unui tabel
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> 14
16. Noţiuni avansate MySQL
Trigger - 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> 15
17. 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> 16
18. 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> 17
19. Noţiuni avansate MySQL
Exemplu procedură stocată
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> 18
20. Noţiuni avansate MySQL
DESCRIBE
• Arată planul de execuţie ales de optimizator
• Arată pentru fiecare tabel din sql : indecşii
folosiţi, tipul căutării, numărul de rânduri prin
care caută, etc
• DESCRIBE [sql]
• Câmpuri
Select_type tip interogare
Table nume tabel
Possible_keys indecși luați în considerare
Key index-ul ales
Key_len lungimea index-ului
Rows nr. aprox. de rânduri prin care caută
Extra file sort, tmp table, etc
Mihai Oaida <mihai.oaida@gmail.com> 19
21. Noţiuni avansate MySQL
DESCRIBE - exemplu
DESCRIBE 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
+----+--------------------+-------+------+---------------+
| id | select_type | table | type | possible_keys |
+----+--------------------+-------+------+---------------+
| 1 | PRIMARY | l | ALL | NULL |
| 3 | DEPENDENT SUBQUERY | r | ref | lectie_id |
| 2 | DEPENDENT SUBQUERY | c | ref | lectie_id |
+----+--------------------+-------+------+---------------+
-----------+---------+-----------------+------+----------------+
key | key_len | ref | rows | Extra |
-----------+---------+-----------------+------+----------------+
NULL | NULL | NULL | 8 | Using filesort |
lectie_id | 2 | web-1-2008.l.id | 182 | |
lectie_id | 2 | web-1-2008.l.id | 91 | |
-----------+---------+-----------------+------+----------------+
Mihai Oaida <mihai.oaida@gmail.com> 20
22. Noţiuni avansate MySQL
Slow query log
Jurnal de interogări lente
Locaţie my.cnf
log_slow_queries = /var/log/mysql/my-slow.log
long_query_time = 2
log-queries-not-using-indexes
Mihai Oaida <mihai.oaida@gmail.com> 21
23. 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> 22
24. 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
NU
SELECT * FROM table ORDER BY RAND() LIMIT 1
SELECT COUNT(*) FROM table
SELECT DISTINCT column FROM table
Mihai Oaida <mihai.oaida@gmail.com> 23
25. Noţiuni avansate MySQL
Resurse
Documenţatie
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/
Unelte
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> 24