Delavnica MySQL

MySQL
FMF delavnica
Vid Podpečan
Inštitut Jožef Stefan, odsek E8
vsi materiali delavnice:
http://ropot.ijs.si/mysql
Potek delavnice
● kratek uvod
○
MySQL, relacijske PB, SQL
● štirje sklopi
○
○
○
○
uporabniki in njihove pravice
načrtovanje in gradnja tabel
poizvedbe v jeziku SQL
uporaba MySQL iz jezika Python
● vsakemu sklopu pripada zbirka vaj, reševali jih bomo sproti
● pri delu se boste povezali na oddaljeni MySQL strežnik
MySQL
● sistem za upravljanje relacijskih podatkovnih baz (RDBMS)
○
○
○
napisan v jezikih C in C++
zastonj (odprta koda - licenca GPL)
deluje v vseh modernih sistemih: Linux, Windows, OS X, Solaris, BSD, ...
● shranjevanje in iskanje podatkov
○
○
podatkov je lahko veliko!
več milijonov zapisov je popolnoma običajna stvar
● drugi najpopularnejši RDBMS
○
prvi je SQLite (ta je prisoten v vsakem brskalniku in pametnem telefonu)
● osnovno poznavanje MySQL je nujno za vse, ki planirajo
kariero v IT industriji
○
programerji, podatkovni analitiki, načrtovalci sistemov, administratorji, …
● večina manjših firm uporablja MySQL (zakaj ?)
Kratka zgodovina MySQL
● 1995
○
Michael Widenius in David Axmark izdata prvo verzijo in ustanovita podjetje
MySQL AB (... zakaj ime MySQL?)
● 2000
○
MySQL dobi dvojno licenco: odprtokodna (GPL) in plačljiva
● 2006
○
○
MySQL ima 33% tržni delež (po številu inštalacij), po prihodkih pa 0.2% …
Firma Oracle poskuša kupiti MySQL AB
■
Oracle je softwerski gigant, znan po agresivnem obnašanju do konkurence...
● 2008
○
Sun Microsystems kupi MySQL AB. Cena: 1 milijarda $
● 2009
○
○
Oracle kupi Sun Microsystems. Cena: 7.4 milijarde $
pred nakupom Michael Widenius naredi fork MariaDB, ki ima le GPL licenco
● 2015:
○
○
MySQL in MariaDB se razvijata ločeno, vendar ostajata kompatibilni
podporniki odprte kode so bolj naklonjeni MariaDB (nezaupanje do Oracla)
Konkurenca MySQL
● open source
○
PostgreSQL
● plačljivi sistemi
○
○
○
○
○
Oracle
Microsoft SQL server
IBM Informix
IBM DB2
...
● za mikro sisteme in testiranje
○
SQLite - najpogosteši RDBMS na svetu (je na vsakem pametnem telefonu in
spletnem brskalniku)
Pogoste kritike MySQL
● počasnost
● slaba podpora SQL standardov
● manjkajoče funkcije (stare verzije MySQL)
●
kaj je res in kaj ni?
○
podpora SQL standardom je slabša kot pri PostgreSQL
○
za doseganje optimalnega delovanje pri večjih obremenitvah je potrebnega
precej znanja
■
■
○
….to velja tudi za ostale RDBMS sisteme!
veliko firm ponuja storitve analize in optimizacije MySQL strežnikov in tudi
prilagojene verzije, npr. Percona server firme Percona
nezadostno poznavanje sistema MySQL je glavni vzrok kritik o hitrosti!
MySQL v praksi
●
zelo tipična uporaba
○
○
LAMP:
hranjenje podatkov v spletnih aplikacijah (spletne trgovine, socialna omrežja, …)
shranjevanje različnih podatkov za kasnejšo analizo
operacijski sistem
spletni strežnik
podatkovna baza
programski jezik
Linux
Apache
MySQL
PHP / Python / Perl
MySQL
Python
API
web framework
(Django, web2py)
Python
MySQL
WSGI
vmesnik
HTTP strežnik
(Apache, Nginx)
spletna
aplikacija
Kako so v MySQL shranjeni podatki
● podatki so shranjeni v tabelah
● tabele pripadajo bazam
● tabele so na disku shranjene v binarnih datotekah
○
○
v obliki dreves (B-drevesa)
drevesa: hiter dostop do podatkov
● dostop do podatkov je možen le preko MySQL!
● povzetek
○
○
○
več baz
vsaka baza ima več tabel
podatki so fizično shranjeni v optimizirani obliki, vidimo pa jih kot tabele
Veliki uporabniki sistema MySQL: Facebook
● podatki iz leta 2011
○
○
○
○
○
800 milijonov uporabnikov
500 milijonov dnevnih obiskov
350 miljonov uporabnikov mobilnih naprav redno objavlja
60 milijonov povpraševanj na sekundo
4 milijone vrstic v tabelah se spremeni vsako sekundo
● takšna velikost presega zmogljivosti običajnih RDBMS inštalacij
● rešitev
○
○
○
pametna razdelitev baze (sharding)
predpomnilnik (programski in strojni)
lastne izboljšave sistema MySQL
● Facebook uporablja tudi druge sisteme
○
HBase, ...
Veliki uporabniki sistema MySQL: Wikipedia
●
●
●
●
LAMP: Linux/Solaris + Apache + MariaDB (MySQL)
~ 400 strežnikov
pametna uporaba predpomnilnika
strukturirani podatki so v gručah, vsaka gruča ima več
MariaDB strežnikov
● slike in objekti so shranjeni ločeno
Kako izgleda delujoča, neprazna MySQL inštalacija?
● obstaja rezerviran direktorij, kjer so shranjene podatkovne baze
● v ozadju teče program mysqld
○
samodejno se požene ob vsakem zagonu računalnika
● na voljo je program mysql (interpreter SQL ukazov)
● lahko imamo tudi grafični vmesnik
○
npr. phpMyAdmin
Kako izgleda MySQL: podatki
● velike binarne datoteke, ki
vsebujejo podatke
● vsaka baza ima svoj direktorij,
vsaka tabela svojo .fdm datoteko
● binarne log datoteke
Kako izgleda MySQL: ukazna vrstica
● ukazna vrstica, ki
interpretira naše
ukaze
● sistemski ukazi in
SQL stavki
● običajno jo
uporabljamo za
administracijo
Kako izgleda MySQL:
web grafični vmesnik phpMyAdmin
● samostojen
program, ni del
MySQL inštalacije
● grafična verzija
ukazne vrstice
Relacijska podatkovna baza
● temelji na relacijskem modelu (E.F. Codd @ IBM, 1970)
○
○
○
predikatni račun prvega reda
podatki so predstavljeni z ntericami, te so združene v relacije
namen: deklarativni pristop k shranjevanju in iskanju podatkov
● proceduralni in deklarativni pristop:
○
imamo tabelo naročnikov revije, želimo poiskati vse, ki so iz Ljubljane in so
mlajši od 30 let:
tu se ukvarjamo s
postopkom iskanja
napišemo postopek
rezultat = [ ]
for x in narocniki:
if x['starost'] < 30 and x['bivalisce'] == 'Ljubljana':
rezultat.append(x['ime'])
return rezultat
ne zanima nas
postopek, ampak
VRNI VSE narocnike
samo rezultat!
KJER VELJA starost < 30 IN bivalisce='Ljubljana'
opišemo, kaj želimo
SQL
● SQL (Structured Query Language)
○
○
○
○
○
programski jezik za obdelavo relacijskih podatkovnih baz
inženirski pristop k relacijskemu modelu
podatki so shranjeni v tabelah
vrstice so zapisi, stolpci so atributi
tabele so med seboj lahko povezane
● dva sestavna dela
○
jezik za definiranje podatkovnih struktur (tabel) - DDL
○
jezik za manipulacijo podatkov: iskanje, vstavljanje, brisanje, spreminjanje DML
● SQL je standardiziran (npr. SQL-92, SQL-2011)
○
vsi RDBMS sistemi ne podpirajo vseh določil standarda
Kako izgleda jezik SQL?
● berljiv, enostavni ukazi v angleščini
● primeri rezerviranih besed
○
select, create, from, where, check, show, view, drop, rename, case...
● sintaksa
○
○
stavki se končajo s podpičjem
velike/male črke niso pomembne, prelom vrstic tudi ne
select from === seLeCT frOM === SELECT FROM
držimo se pravila, da SQL ukaze pišemo z veliko, gremo v novo vrsto in poravnamo
○
nizi in podobno so v enojnih narekovajih
● primer lepo oblikovanega SQL
SELECT ime
FROM narocniki
WHERE starost >= 18
AND
bivalisce = 'Ljubljana'
ORDER BY priimek ASC
LIMIT 5;
Kaj boste znali po končani delavnici
● osnovna uporaba MySQL ukazne vrstice
○
○
○
kreiranje baze
dodajanje uporabnikov in upravljanje privilegijev
uvoz in izvoz podatkov iz datotek
● delo s tabelami
○
○
○
osnove načrtovanja podatkovne baze
ustvarjanje tabel in povezav med njimi
vstavljanje, brisanje, spreminjanje podatkov
● SQL poizvedbe
○
●
●
●
osnovne SQL poizvedbe
■
■
osnovni select, operatorji, urejanje, združevalne funkcije
združevanje tabel
● MySQL in Python
○
○
česa ne bomo spoznali
●
●
namestitev in konfiguracija
sistema MySQL
teorija relacijskih podatkovnih
baz in relacijska algebra
napredno načrtovanje
podatkovnih in normalizacija
podatkovnih baz
kompleksne SQL poizvedbe in
MySQL procedure
optimizacija MySQL
povezava na MySQL strežnik
izvajanje SQL stavkov
→ večina pridobljenega znanja ni vezana na MySQL in velja tudi za druge RDBMS!
MySQL v praksi
Uporabniki in njihove
pravice
Uporabniki v sistemu MySQL
● MySQL je večuporabniški sistem
● uporabniki se lahko prijavijo lokalno ali oddaljeno
○
○
lokalno: localhost, 127.0.0.1
oddaljeno: ime računalnika, ip naslov
● root je uporabnik, ki ima vse pravice (administrator)
○
anonimni uporabnik: nima imena in pravic
● ko začnemo uporabljati svež sistem MySQL:
○
naredimo novega uporabnika in mu damo tiste pravice, ki jih trenutno potrebuje
● pomembno
○
○
root je namenjen IZKLJUČNO za administracijo, prijavlja se IZKLJUČNO lokalno
uporabnikom dajmo le toliko pravic, kot jih nujno rabijo (vedno jih lahko razširimo)
Ustvarjanje in brisanje uporabnikov
● predpogoj: smo root oz. imamo pravice za dodajanje uporabnikov
● sintaksa
CREATE USER 'ime'@'lokacija' IDENTIFIED BY 'geslo';
● primer
○
uporabnik miha, ki bo lahko dostopal lokalno, iz domene fmf.uni-lj.si in od kjerkoli:
CREATE USER 'miha'@'localhost' IDENTIFIED BY 'a1b2c3';
CREATE USER 'miha'@'%.fmf.uni-lj.si' IDENTIFIED BY 'a1b2c3';
CREATE USER 'miha'@'%' IDENTIFIED BY 'a1b2c3';
● spreminjanje gesla
○
za sebe in za drugega uporabnika (slednje zahteva dodatne pravice - zakaj?)
SET PASSWORD = PASSWORD('a1b2c3');
SET PASSWORD FOR 'miha'@'localhost' = PASSWORD('a1b2c3');
● brisanje:
DROP USER 'miha'@'localhost'; DROP USER 'miha'@'%';
Ustvarjanje in brisanje uporabnikov
● uporabnik lahko ima različna dovoljenja za različne lokacije
● zato sta to dva različna računa in dve gesli:
○
○
'miha'@'localhost'
'miha'@'%'
● če lokacije ne podamo, je privzeto %!
○
'miha' je enako 'miha'@'%'
● če želimo lokalen in oddaljen dostop, moramo dodati oba!
○
○
% ne vključuje localhost
localhost ima v MySQL poseben status
Pravice uporabnikov
● ko dodamo novega uporabnika, je brez pravic
○
USAGE pravica je sinonim za “nič pravic”
● več nivojev
○
○
○
globalni: *.*
baza: imebaze.*
tabela: imebaze.imetabele
● osnovna sintaksa: dodajanje in odvzem pravic
GRANT pravica ON baza.tabela TO 'ime'@'lokacija';
REVOKE pravica ON baza.tabela FROM 'ime'@'lokacija';
● veliko vrst, najpogostejši so
○
○
○
○
○
ALL - poln dostop do baze/tabele
CREATE - lahko kreiramo baze/tabele
DROP - lahko brišemo baze/tabele
DELETE, INSERT, SELECT, UPDATE - delo s tabelami
GRANT OPTION - svoje pravice lahko dajemo tudi drugim
● pomembno:
○
spreminjanje pravic vedno zaključimo z ukazom flush privileges;
■
sicer bodo stopili v veljavo šele ob naslednjem zagonu MySQL
Primeri
●
prikaz pravic
trenutni uporabnik: SHOW GRANTS;
izbrani uporabnik: SHOW GRANTS FOR 'miha'@'localhost';
●
vse pravice za bazo nakupi (vse tabele)
GRANT ALL PRIVILEGES ON nakupi.* TO 'miha'@'localhost';
●
vse pravice za vse baze, ki se začnejo s predpono fmf_
GRANT ALL PRIVILEGES ON `fmf_%`.* to 'miha'@'localhost';
●
○ pazi: uporabljeni sta dve različni vrsti narekovajev!!
odvzem vseh pravic:
REVOKE ALL PRIVILEGES ON nakupi.* FROM 'miha'@'localhost';
Delo z bazami
● ukaz, ki naredi novo, prazno bazo
○
CREATE DATABASE imeBaze;
● ukaz, ki izbriše bazo in vse v njej
○
DROP DATABASE imeBaze;
● vse baze prikažemo z ukazom
○
SHOW DATABASES;
● bazo začnemo uporabljati z ukazom:
○
USE imeBaze;
● ne pozabi: potrebujemo ustrezne pravice!
Vaja 1
1.
2.
3.
4.
prijava na oddaljeni računalnik preko ssh
prijava v sistem MySQL
prikaz pravic
kreiranje nove prazne baze
Načrtovanje baze in
gradnja tabel
Postopek gradnje podatkovne baze
● korak 1: načrt (svinčnik in list papirja)
○
○
○
ugotovimo, kaj vse bomo shranjevali
določimo tabele, stolpce in tip podatkov
določimo povezave med tabelami (če so)
● korak 2: programiranje v SQL
○
○
opis tabel in stolpcev pretvorimo v SQL ukaze
tabele napolnimo s podatki ali pa pripravimo vmesnik (npr. spletna stran)
Entitete in tabele
● kaj je entiteta
○
○
oseba, stvar, dogodek
vsaki entiteti pripada ena tabela
● vrstica v tabeli
○
○
konkretni primerek entitete
vrstni red vrstic ni pomemben, ne sme pa biti duplikatov
● stolpec v tabeli
○
lastnost (atribut) entitete
● celica v tabeli
○
vrednost lastnosti nekega primerka, prazna celica: vrednost NULL
● primer: tabela o študentih
vpisna številka
ime
priimek
datum rojstva
letnik
63140123
Janez
Novak
1.4.1990
1
63140124
Miha
Novak
14.12.1989
2
63131421
Tone
Turnšek
7.1.1988
NULL
Gradnja tabel: osnovni napotki
● ne poskušajmo vsega stlačiti v eno tabelo!!
○
○
pravilo: če stolpec ne opisuje lastnosti entitete, ne spada v njeno tabelo
npr. če bi imeli v tabeli študenti stolpca stalno bivališče in poštna številka
■
očitno je, da moramo narediti novo tabelo kraji za entiteto kraj
● vsaka tabela mora imeti primarni ključ
○
stolpec (ali kombinacija stolpcev), ki je unikaten za vsako vrstico v tabeli
■
○
EMŠO, vpisna številka
zelo zelo pogosto: dodaten stolpec z imenom id (celo število)
● atributi (stolpci) naj bodo neodvisni med sabo
○
●
npr. če bi imeli stolpca datum rojstva in starost
nabor vrednosti atributov naj atomaren
○
vrednosti v celicah ne smejo biti množice!
■ stolpec bivališče, ki ima vrednosti oblike “Dunajska 24, 1000 Ljubljana”
■
stolpec vpisani predmeti v tabeli študenti, vrednosti oblike “analiza 2; programiranje 2”
Normalizacija
● normalizacija je odpravljanje odvisnosti med atributi, ki
povzročajo anomalije pri uporabi (vstavljanje, brisanje,
spreminjanje)
○
NF - normalne oblike (>): prva, druga, tretja, Boyce-Coddova, četrta, peta
● postopek: tabele razdelimo in jih povežemo s tujimi ključi
● ni obvezna
○
○
RDBMS dovoli kakršnekoli tabele
slaba zasnova je strel v koleno!
predmet
● 1NF je minimum
○
○
domene atributov vsebujejo samo atomarne vrednosti
vrednost atributa je ena sama (ne pa npr. množica)
● primer: tabela, ki ni v 1NF
predmet
uvod v programiranje
podatkovne baze
vsebina
vsebina
uvod v programiranje
Python
uvod v programiranje
C++
uvod v programiranje
Java
podatkovne baze
MySQL
podatkovne baze
PostgreSQL
Python, C++, Java
MySQL, PostgreSQL
Relacije med entitetami (tabelami)
ER diagram (entity relationship)
● 1:1
○
primer: oseba in rojstni list
■
relaciji: oseba ima rojstni list, rojstni list je izdan za
■
osebo
vsaka oseba ima ntk. en rojstni list
● 1:N
○
primer: oseba in bančni račun
■
relaciji: oseba je lastnik bančnega računa, bančni račun
je v lasti osebe
■
ena oseba lahko ima več bančnih računov, en bančni
račun pripada le eni osebi
● N:M
○
primer: študent in predavatelj
■
relaciji: študent posluša predavanja predavatelja,
predavatelj predava študentu
■
en študent lahko posluša več predavateljev, en
predavatelj predava več študentom
Relacije med tabelami v praksi
● dodamo stolpec, ki “kaže” na stolpec v drugi tabeli
● primer:
EMŠO
ime
priimek
številka
stanje
limit
lastnik
2305990500243
Janez
Novak
134512
2000
500
2305990500243
1210992500631
Miha
Novak
12415
50500
2000
2305990500243
1903983500510
Tone
Turnšek
97123
1240
200
1903983500510
● takemu stolpcu pravimo tuji ključ (foreign key)
○
naslavlja primarni ključ v prvi tabeli
● očitno je, da ne sme vsebovati vrednosti, ki jih v prvi tabeli ni
○
to je referenčna integriteta
○
tudi ni dovoljeno brisanje, ki bi vodilo v nesmiselno stanje (npr. neobstoječi
lastnik)
Kako naredimo tabelo v MySQL
● SQL ukaz CREATE TABLE ime
○
brisanje: DROP TABLE ime
● osnovna oblika:
CREATE TABLE imeTabele (
imeStolpca1 tipStolpca1 [opcije],
imeStolpca2 tipStolpca2 [opcije],
imeStolpca3 tipStolpca3 [opcije],
…
[opcije]
);
● nastavimo lahko veliko stvari
○
○
primarni ključ, tuji ključ, indeks
omejitve vrednosti, npr. >0, neprazno, unikatno, privzeta vrednost, ...
MySQL podatkovni tipi
● tri skupine tipov
● numerični tipi
○
○
cela števila: INTEGER, BIGINT (do 232 oz. 264)
realna števila: FLOAT, DOUBLE
● čas in datum
○
○
○
datum: DATE (oblika “YYYY-MM-DD”)
čas: TIME (oblika “hh:mm:ss”)
kombinacija: DATETIME (oblika “YYYY-MM-DD hh:mm:ss”)
● nizi
○
○
○
○
CHAR (n)
-- niz do dolžine n (če je krajši, se dopolni s presledki)
VARCHAR (n)
-- niz do dolžine n (shrani se takšen kot je)
TEXT, LONGTEXT -- doooooolgi nizi (64KB, 4GB)
BINARY, VARBINARY, BLOB
■
podobni kot CHAR, VARCHAR, le da so nizi zaporedja bajtov, ne znakov
●
character set ni definiran, primerjava je po numerični vrednosti bajtov
Primer: bančni računi in osebe
● atributi
○
○
oseba: ime, priimek, EMŠO, davčna številka, datum rojstva
račun: številka računa, stanje, limit
● primarna ključa
○
EMŠO in številka računa
CREATE TABLE osebe (
EMSO
CHAR(13)
ime
VARCHAR(20)
priimek VARCHAR(50)
davcna CHAR(8)
PRIMARY KEY (EMSO)
);
NOT
NOT
NOT
NOT
NULL,
NULL,
NULL,
NULL UNIQUE,
CREATE TABLE racuni (
stevilka INTEGER NOT NULL,
stanje
BIGINT,
`limit`
INTEGER,
PRIMARY KEY (stevilka)
);
● vprašanji:
○
○
zakaj je stolpec limit v poševnih enojnih narekovajih?
kaj še manjka?
Primer: bančni računi in osebe
● končna oblika
CREATE TABLE osebe (
EMSO
CHAR(13)
ime
VARCHAR(20)
priimek VARCHAR(50)
davcna CHAR(8)
PRIMARY KEY (EMSO)
);
NOT
NOT
NOT
NOT
NULL,
NULL,
NULL,
NULL UNIQUE,
CREATE TABLE racuni (
stevilka INTEGER NOT NULL,
stanje
BIGINT,
`limit`
INTEGER,
lastnik
CHAR(13),
PRIMARY KEY (stevilka),
FOREIGN KEY (lastnik) REFERENCES osebe(EMSO)
);
● za lenuhe: avtomatska pretvorba ER→ create table
○
https://editor.ponyorm.com/user/vpodpecan/osebe_in_racuni
Vstavljanje vrstic v tabelo
CREATE TABLE racuni (
stevilka INTEGER NOT NULL,
stanje
BIGINT,
`limit`
INTEGER,
lastnik
CHAR(13),
PRIMARY KEY (stevilka),
FOREIGN KEY (lastnik) REFERENCES osebe(EMSO)
);
● SQL ukaz INSERT INTO ...
● osnovna oblika
○
CREATE TABLE osebe (
EMSO
CHAR(13)
ime
VARCHAR(20)
priimek VARCHAR(50)
davcna CHAR(8)
PRIMARY KEY (EMSO)
);
NOT
NOT
NOT
NOT
NULL,
NULL,
NULL,
NULL UNIQUE,
tu mora biti vrstni red enak kot pri stavku CREATE!
INSERT INTO osebe VALUES ('2305990500243', 'Janez', 'Novak', '12345678');
INSERT INTO racuni VALUES (1025, 12500, 1200, '2305990500243');
● razširjena oblika ter več naenkrat
○
vrstni red povemo sami, lahko tudi kakšen stolpec izpustimo (če sme biti NULL)
INSERT INTO osebe (EMSO, ime, priimek, davcna) VALUES ('1210992500631',
'Miha', 'Novak', '45675432');
INSERT INTO racuni (stevilka, lastnik) VALUES (3412, '1210992500631'),
(5253, '1210992500631'), (5541, '2305990500243');
Vstavljanje v tabelo - nasveti
● izogbajmo se čudnim znakom pri imenih tabel (šumniki ipd.)
○
○
je sicer dovoljeno, ni pa priporočljivo
če že nujno moramo uporabiti nestandardna imena: backtick `
■
npr. CREATE TABLE `čudna<<;'+tabela` (....
● kadar je primarni ključ celo število
○
mu dodamo opcijo AUTO_INCREMENT, pa ga ne bo potrebno vstavljati in
○
skrbeti, da je vedno unikaten
primer: stevilka INTEGER NOT NULL AUTO_INCREMENT,
● v CREATE dodamo smiselne opcije, ki nam kasneje
pomagajo pri vstavljanju
○
○
npr. NOT NULL, CHECK (stolpec > 0), UNIQUE, DEFAULT
POZOR: MySQL dovoli, ampak ignorira CHECK omejitve!!!
Narekovaji v MySQL
● enojni: '
○
najpogostejši, uporaba pri nizih
● backtick: `
○
kadar imamo čudna imena tabel in stolpcev
■
○
ni ANSI standard!
■
○
čudni znaki, presledki, rezervirane besede
PostgreSQL za to uporablja dvojne narekovaje
uporabimo le, če je nujno, boljša so lepa imena, ki ne rabijo `
● dvojni: "
○
v MySQL tudi dovoljeni za nize, vendar to ni ANSI standard!
■
v MySQL se jih izogibamo, ker ne bomo kompatibilni z ostalimi RDBMS (PostgreSQL, …)
INSERT INTO `table` (`column`, `select`, `čšž`) VALUES (NULL, "blah", 'aaa');
Velike in male črke v MySQL
● SQL ukazi: velikost črk ni važna
● MySQL: imena baz, tabel, stolpcev
○
odvisno od operacijskega sistema!!
■
■
○
○
vzrok: bazi pripada direktorij z istim imenom, tabeli ena ali več datotek, ...
Linux: sensitive, Windows: insensitive
baze in tabele: odvisno od sistema
stolpci, indeksi: velikost črk ni važna
MySQL: uvoz podatkov iz tekstovnih datotek
● npr. imamo .csv datoteke iz Excela
● SQL ukaz LOAD DATA …
● primer:
LOAD DATA INFILE 'podatki.csv' INTO TABLE mojaTabela
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n';
● tabela, v katero vstavljamo, mora že obstajati
○
mora se tudi ujemati s podatki
● veliko dodatnih možnosti
○
preskok začetnih n vrstic, vrednosti v narekovajih, …
● potrebna je FILE pravica
○
GRANT FILE ON … TO …
MySQL: izvoz podatkov v tekstovne datoteke
● npr. izbrane podatke želimo obdelati z Excelom
● SQL ukaz SELECT… INTO OUTFILE
● primer
SELECT col1, col2,... INTO OUTFILE 'izvoz.csv'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM mojaTabela;
● potrebna je FILE pravica
MySQL: uvoz in izvoz SQL ukazov
● uvoz SQL ukazov iz datoteke
○
znotraj MySQL ukazne lupine
mysql> source imeDatoteke.sql
● izvoz v datoteko z SQL ukazi
○
○
○
sistemsko orodje mysqldump
izvozi celo bazo ali pa le izbrano tabelo (skupaj s stavki CREATE TABLE)
lahko izvozi tudi SQL ukaze posebej in podatke posebej (tab-delimited)
student@vihar:~$ mysqldump -u fmf -p imeBaze imeTabele
● uporabno za varnostne kopije in prenos med strežniki
Vaja 2
1. kreiranje tabel osebe in racuni
2. polnjenje tabel s podatki
3. kreiranje dodatne tabele banke
Delo s podatki:
poizvedbe v jeziku SQL
SQL
● SQL za ustvarjanje struktur že poznamo (CREATE TABLE)
● SQL za obdelavo podatkov
○
iskanje, brisanje, spreminjanje
● ne pozabimo
○ delamo s tabelami, rezultat iskanja je tabela!
● osnovna oblika:
SELECT seznam stolpcev, ki jih želimo videti
FROM seznam tabel, kjer so željeni podatki
WHERE pogoji, ki določajo katere podatke želimo videti;
Testni podatki
● dve tabeli, relacija 1:N
○
○
osebe
računi
tuji ključ
EMŠO
ime
priimek
davcna
številka
stanje
limit
lastnik
2305990500243
Janez
Novak
12345678
134512
2000
500
2305990500243
1210992500631
Miha
Novak
45675432
12415
50500
2000
2305990500243
1903983500510
Tone
Turnšek
77774433
97123
1240
200
1903983500510
134511
120
800
1210992500631
6531
5502
2000
1210992500631
Primer 1
● vse osebe, ki se pišejo Novak
EMŠO
SELECT ime, priimek
FROM
osebe
WHERE priimek = 'Novak';
ime
priimek
2305990500243
Janez
Novak
1210992500631
Miha
Novak
1903983500510
Tone
Turnšek
● kaj vrne MySQL
mysql> select ime, priimek from osebe where priimek = 'Novak';
+-------+---------+
| ime
| priimek |
+-------+---------+
| Miha | Novak
|
| Janez | Novak
|
+-------+---------+
Primer 2
● vsi podatki o osebah, ki se jim priimek konča na “ak”
SELECT *
FROM
osebe
WHERE priimek LIKE '%ak';
● kaj vrne MySQL
mysql> SELECT * FROM osebe WHERE priimek LIKE '%ak';
+---------------+-------+---------+----------+
| EMSO
| ime
| priimek | davcna
|
+---------------+-------+---------+----------+
| 1210992500631 | Miha | Novak
| 45675432 |
| 2305990500243 | Janez | Novak
| 12345678 |
+---------------+-------+---------+----------+
Primer 3
● največje in najmajše stanje na računih
SELECT MAX(stanje), MIN(stanje)
FROM racuni;
● kaj vrne MySQL
mysql> SELECT MAX(stanje), MIN(stanje) FROM racuni;
+-------------+-------------+
| MAX(stanje) | MIN(stanje) |
+-------------+-------------+
|
53000 |
-10000 |
+-------------+-------------+
Primer 4
● lastniki računov (EMŠO), kjer je naloženih več kot 10000
evrov in je limit večji od 200 evrov
SELECT DISTINCT lastnik
FROM
racuni
WHERE stanje>10000 AND `limit`>200;
● kaj vrne MySQL
mysql> select distinct lastnik from racuni where stanje>10000 and
`limit`>200;
+---------------+
| lastnik
|
+---------------+
| 1210992500631 |
| 2305990500243 |
+---------------+
● DISTINCT pove, da ne želimo duplikatov
Primer 5
● vse o računih, ki imajo stanje manjše od največjega, urejeno
padajoče po stanju
SELECT *
FROM racuni
WHERE stanje <(SELECT MAX(stanje)
FROM racuni
LIMIT 1)
ORDER BY stanje DESC;
+----------+--------+-------+---------------+
| stevilka | stanje | limit | lastnik
|
+----------+--------+-------+---------------+
|
1025 | 12500 | 1200 | 2305990500243 |
|
3412 | 12500 |
300 | 1210992500631 |
|
5541 |
-250 |
100 | 2305990500243 |
|
6666 | -10000 |
0 | 2111978500222 |
+----------+--------+-------+---------------+
Primer 6
● koliko računov imajo lastniki?
SELECT lastnik, COUNT(stevilka)
FROM
racuni
GROUP BY lastnik;
mysql> SELECT lastnik, COUNT(stevilka) FROM racuni GROUP BY lastnik;
+---------------+-----------------+
| lastnik
| COUNT(stevilka) |
+---------------+-----------------+
| 1210992500631 |
2 |
| 2111978500222 |
1 |
| 2305990500243 |
2 |
+---------------+-----------------+
● GROUP BY zruži vrstice glede na isto vrednost
● COUNT šteje vrstice
Povzetek
- imena stolpcev
- funkcije: MIN, MAX, AVG, SUM, COUNT, FIRST, LAST,
LEN,...
- DISTINCT
SELECT stolpci
FROM tabele
WHERE pogoji
[...]
- GROUP BY
- HAVING
- ORDER BY
- LIMIT
- ime ene tabele ali več združenih tabel
- lahko tudi vgnezdeni select: (SELECT…) AS ime
- aritmetika: +, -, *, /, %
- primerjave: =, !=, >, <, <=, >=
- logični operatorji: AND, OR, NOT, IS NULL, LIKE, UNIQUE,
BETWEEN, EXISTS, ALL, ANY, IN
- lahko tudi vgnezdeni select: (SELECT…)
Združevanje tabel
● imamo več tabel, ki so povezane
● želimo rezultat, ki vsebuje stolpce iz večih tabel
● primer
○
vsi podatki o lastniku najbogatejšega računa
● kako združimo tabeli?
○
upoštevamo povezave med tabelami, velja: lastnik = EMŠO
številka
EMŠO
ime
priimek
davcna
2305990500243
Janez
Novak
12345678
1210992500631
Miha
Novak
45675432
1903983500510
Tone
Turnšek
77774433
+
stanje
limit
lastnik
134512
2000
500
2305990500243
12415
50500
2000
2305990500243
97123
1240
200
1903983500510
134511
120
800
1210992500631
6531
5502
2000
1210992500631
Primer rezultata združevanja
EMSO
ime
priimek
davcna
stevilka
stanje
limit
lastnik
2305990500243
Janez
Novak
12345678
1025
12500
1200
2305990500243
1210992500631
Miha
Novak
45675432
3412
12500
300
1210992500631
1210992500631
Miha
Novak
45675432
5253
53000
1500
1210992500631
2305990500243
Janez
Novak
12345678
5541
-250
100
2305990500243
2111978500222
Tone
Turnsek
77774433
6666
-10000
0
2111978500222
● koliko vrstic ima tabela in zakaj?
Načini združevanja (stiki tabel)
● SQL operacija JOIN
● več vrst
● v praksi najpogostejši: notranji stik
○
kombinacije vrstic, ki se ujemajo v vrednostih podanih stolpcev
tabela1 INNER JOIN tabela2 ON tabela1.stolpecA=tabela2.stolpecB
● ostale vrste stikov
○
kartezični produkt
■
○
○
tabela1 CROSS JOIN tabela2
naravni stik
zunanji stiki: levi, desni, polni
Primer združevanja 1
● vse informacije o osebah in njihovih računih
SELECT *
FROM osebe INNER JOIN racuni ON osebe.EMSO = racuni.lastnik;
mysql> SELECT * FROM osebe INNER JOIN racuni ON osebe.EMSO = racuni.lastnik;
+---------------+-------+---------+----------+----------+--------+-------+---------------+
| EMSO
| ime
| priimek | davcna
| stevilka | stanje | limit | lastnik
|
+---------------+-------+---------+----------+----------+--------+-------+---------------+
| 2305990500243 | Janez | Novak
| 12345678 |
1025 | 12500 | 1200 | 2305990500243 |
| 1210992500631 | Miha | Novak
| 45675432 |
3412 | 12500 |
300 | 1210992500631 |
| 1210992500631 | Miha | Novak
| 45675432 |
5253 | 53000 | 1500 | 1210992500631 |
| 2305990500243 | Janez | Novak
| 12345678 |
5541 |
-250 |
100 | 2305990500243 |
| 2111978500222 | Tone | Turnsek | 77774433 |
6666 | -10000 |
0 | 2111978500222 |
+---------------+-------+---------+----------+----------+--------+-------+---------------+
● vidimo, da se stolpca EMSO in lastnik ujemata
Primer združevanja 2
● koliko računov imajo osebe, z imeni in priimki
SELECT osebe.ime, osebe.priimek, COUNT(racuni.lastnik) AS st_racunov
FROM
osebe INNER JOIN racuni ON osebe.EMSO = racuni.lastnik
GROUP BY racuni.lastnik;
mysql> SELECT osebe.ime, osebe.priimek, COUNT(racuni.lastnik) AS st_racunov FROM
osebe INNER JOIN racuni ON osebe.EMSO = racuni.lastnik GROUP BY racuni.lastnik;
+-------+---------+------------+
| ime
| priimek | st_racunov |
+-------+---------+------------+
| Miha | Novak
|
2 |
| Tone | Turnsek |
1 |
| Janez | Novak
|
2 |
+-------+---------+------------+
● POZOR:
○
kaj je v teoriji narobe, če imamo GROUP BY in SELECT stolpec1,stolpec2,... ?
■
■
○
primer: če bi grupirali po priimku
če imamo GROUP BY, lahko SELECT načeloma vsebuje samo grupirne funkcije (MIN, MAX, COUNT, …)
zakaj je zgornja poizvedba vseeno pravilna in deluje pravilno?
■
ker grupiramo po primarnem ključu in ne more priti do več možnosti pri izpisu stolpca
Primer združevanja 3
● osebe, ki imajo več kot en račun
SELECT osebe.ime, osebe.priimek, COUNT(racuni.lastnik) AS st_racunov
FROM osebe INNER JOIN racuni ON osebe.EMSO = racuni.lastnik
GROUP BY racuni.lastnik
HAVING COUNT(racuni.lastnik)>1;
mysql> SELECT osebe.ime, osebe.priimek, COUNT(racuni.lastnik) AS st_racunov FROM
osebe INNER JOIN racuni ON osebe.EMSO = racuni.lastnik GROUP BY racuni.lastnik
HAVING COUNT(racuni.lastnik)>1;
+-------+---------+------------+
| ime
| priimek | st_racunov |
+-------+---------+------------+
| Miha | Novak
|
2 |
| Janez | Novak
|
2 |
+-------+---------+------------+
●
HAVING
○ povemo, da morajo grupirane vrednosti zadoščati pogojem
Brisanje, spreminjanje
● brisanje vrstic
○
○
○
○
DELETE FROM imeTabele [WHERE pogoji];
če pogojev ni, izbrišemo vse!!
primer:
DELETE FROM osebe WHERE priimek = 'Novak';
● spreminjanje vsebine
○
○
○
UPDATE imeTabele SET stolpec1=vrednost1,... [WHERE pogoji];
primer:
UPDATE osebe SET ime='Anton' WHERE emso=’2111978500222’;
● spreminjanje tabel
○
○
○
○
ukaz ALTER TABLE
brisanje stolpca 'davcna': ALTER TABLE osebe DROP davcna;
dodajanje stolpca:
ALTER TABLE osebe ADD bivalisce VARCHAR(20);
preimenovanje tabele: ALTER TABLE osebe RENAME TO ljudje;
Indeksi
● indeksi omogočajo učinkovito lociranje podatkov
● spomnimo se
○
○
kakšna je zahtevnost iskanja v neurejenem seznamu?
O(n)
kakšna je zahtevnost, če seznam uredimo ali zgradimo drevo? O(log(n))
● za primarni ključ se indeks zgradi avtomatsko
● v praksi so indeksi nujni!
●
○ za tiste stolpce, ki pogosto nastopajo v poizvedbah
○ gradnja je časovno in prostorsko zahtevna
○ se avtomatsko osvežujejo ob spremembah tabele
običajno jih določimo že znotraj create table, lahko pa dodamo tudi kasneje:
CREATE INDEX imeIndeksa ON tabela(stolpci);
Pogledi (views)
● pogled je virtualna tabela (narejena iz rezultata SELECT)
● pogledi se vedno računajo sproti
○
uporabnik nima nobenega dodatnega dela
● primer
○
○
○
ustvarimo pogled
pogled uporabimo v poizvedbi kot tabelo
pogled izbrišemo
CREATE VIEW tajkuni AS
SELECT osebe.ime, osebe.priimek, stanje
FROM osebe INNER JOIN racuni ON osebe.EMSO = racuni.lastnik
WHERE stanje >= 10000000;
SELECT ime, priimek
FROM
tajkuni;
DROP VIEW tajkuni;
Vaja 3
1. gradnja baze z izvajanjem SQL ukazov iz tekstovne datoteke
2. trening SQL poizvedb
MySQL in Python
MySQL konektorji
● podpora za veliko jezikov
○
Java, Python, C++, C, C#, PHP, Perl, Ruby, R, Tcl, Eiffel,
● uporaba MySQL iz različnih jezikov je zelo podobna
● kaj potrebujemo
○
○
knjižnico, ki implementira MySQL API
podatke za prijavo v MySQL: ime, geslo, naslov strežnika
MySQL in Python
● več paketov, za različne verzije Pythona
○
○
○
vse uporabljamo na enak način, ker upoštevajo Python DB-API specifikacijo
Python 2.X: PyMySQL, MySQLdb1
Python 3: PyMySQL, mysqlclient (nadgradnja MySQLdb1)
● priporočeno je uporabljati PyMySQL, ker je napisan v čistem
Pythonu in deluje tudi brez namestitve!
MySQL in Python: postopek
1. vzpostavimo povezavo
a.
potrebujemo uporabniško ime, geslo in ime podatkovne baze
2. naredimo kurzor objekt
a.
kurzor je struktura, ki omogoča sprehajanje po zapisih v bazi
3. na kurzorju izvajamo SQL ukaze
a.
iskanje, vstavljanje, brisanje, …
i.
ii.
če želimo uveljaviti spremembe, moramo na kurzorju poklicati funkcijo commit()
če želimo razveljaviti spremembe, na kurzorju pokličemo funkcijo rollback()
4. ko končamo delo, zapremo kurzor in povezavo
a.
funkcija close() na obeh
MySQL in Python: recept
import pymysql as mdb
connection = mdb.connect(host='vihar.ijs.si',
user='fmf',
password='fmfdelavnica',
database='IME BAZE')
with connection:
cursor = connection.cursor(mdb.cursors.DictCursor)
cursor.execute('SELECT * FROM osebe')
for row in cursor:
print (row)
cursor.close()
connection.close()
MySQL in Python: nasveti
● uporabljamo Python stavek with
○
○
with connection: …
commit() oz. rollback() se bosta izvedla avtomatsko na koncu
■
■
vse v redu: commit()
napaka: rollback() -- poskrbi, da baza ostane konsistentna!
● kurzor podpira iterator protokol zato:
○
for vrstica in cursor:
● pri iskanju lahko kurzor vrača tuple ali slovar
○
○
privzeto se vrača tuple
slovar je lažji za uporabo ker ni važen vrstni red
■
pymysql.cursors.DictCursor
● poleg iteratorja imamo na voljo še
○
○
○
cursor.fetchone()
cursor.fetchmany(n)
cursor.fetchall()
MySQL in Python: primeri
cursor = connection.cursor(mdb.cursors.DictCursor)
cursor.execute('select * from osebe')
for row in cursor:
print (row)
{'ime': 'Miha', 'priimek': 'Novak', 'EMSO': '1210992500631', 'davcna': '45675432'}
{'ime': 'Tone', 'priimek': 'Turnsek', 'EMSO': '2111978500222', 'davcna': '77774433'}
{'ime': 'Janez', 'priimek': 'Novak', 'EMSO': '2305990500243', 'davcna': '12345678'}
cursor = connection.cursor()
cursor.execute('select * from osebe')
for row in cursor:
print (row)
('1210992500631', 'Miha', 'Novak', '45675432')
('2111978500222', 'Tone', 'Turnsek', '77774433')
('2305990500243', 'Janez', 'Novak', '12345678')
MySQL in Python: primeri
cursor.execute('CREATE TABLE banke (SWIFT char(20), ime varchar(20) NOT NULL UNIQUE, kraj varchar(20)
NOT NULL, kapital bigint, PRIMARY KEY(SWIFT))')
data = [('BNK1235123', 'Volksbank', 'Ljubljana', 250000000),
('BNK62346123', 'PBS', 'Maribor', 20000000),
('BNK987987', 'NLB', 'Ljubljana', 35000000)]
for new in data:
cursor.execute('INSERT INTO banke (SWIFT, ime, kraj, kapital) VALUES (%s, %s, %s, %s)', new)
cursor.execute('SELECT ime, SWIFT FROM banke WHERE kapital>%s AND kraj=%s', (40000000, 'Ljubljana'))
banke = cursor.fetchall()
print (banke)
>> [{'SWIFT': 'BNK1235123', 'ime': 'Volksbank'}]
cursor.execute('DROP TABLE IF EXISTS banke')
Objektno-relacijska preslikava (ORM)
● dodaten nivo abstrakcije nad MySQL konektorjem
● entitete iz podatkovne baze predstavimo z razredom v
programskem jeziku
○
○
○
definicija razreda se preslika v definicijo tabele
primerek razreda je vrstica v tabeli
stolpec je atribut razreda
● SQL jezika ne uporabljamo več direktno!
○
ustvarjamo in brišemo objekte, kličemo metode
● potrebujemo ORM knjižnico in konektor za bazo
● Python
○
○
Django (poleg ostalega ima tudi ORM)
SQLAlchemy, Pony ORM, Storm
Primer ORM: Python in Django
from django.db import models
class Oseba(models.Model):
EMSO = models.CharField(max_length=13, primary_key=True)
ime = models.CharField(max_length=20)
priimek = models.CharField(max_length=50)
davcna = models.CharField(max_length=8)
class Racun(models.Model):
stevilka = models.IntegerField(primary_key=True)
stanje = models.IntegerField()
limit = models.IntegerField()
lastnik = models.ForeignKey(Oseba)
● ne pišemo več stavkov CREATE TABLE
○
tabele za nas zgradi Django z uporabo teh razredov!
ORM: primeri uporabe
● namesto s tabelami delamo z objekti
● primeri
○
namesto select * from osebe;
Oseba.objects.all()
○
namesto select * from osebe where ime='Miha';
Oseba.objects.filter(ime='Miha')
○
namesto INSERT INTO OSEBE VALUES ('2305990500243', ...');
nov = Oseba(EMSO='2305990500243', ime='Miha' ,...)
nov.save()
● manj možnosti za napake, enako za vse baze (MySQL,
Postgre, Oracle, …)
● jezika SQL ne potrebujemo več :)
○
razen za zelo zapletene poizvedbe
Vaja 4
1. uporaba sistema MySQL iz jezika Python (modul PyMySQL)
Zaključek
Povzetek delavnice
● osnovna uporaba sistema MySQL + osnove podatkovnih baz
○
○
○
○
○
○
ukazna vrstica, phpMyAdmin
uporabniki in njihove pravice
načrtovanje podatkovne baze, relacije in kardinalnost, ER diagram
podatkovni tipi, delo s tabelami, izvoz in uvoz
SQL poizvedbe
MySQL in Python, ORM
Kako nadaljevati?
● namestite si MySQL na domači računalnik
○
○
še enkrat naredite vaje
eksperimentirajte!!!
● lotite se začetniške literature iz naslednjih področij
○
○
○
namestitev in konfiguracija MySQL
SQL poizvedbe
razvoj spletnih aplikacij z LAMP
■
Linux, Apache, MySQL, Python, Django
Spletni viri za učenje in pomoč
● tutoriali in šole
○
○
○
○
Zetcode: http://zetcode.com/databases/mysqltutorial/
Tutorialspoint: http://www.tutorialspoint.com/mysql/index.htm
W3Scools: http://www.w3schools.com/sql/
SQLZoo: http://sqlzoo.net
● dokumentacija, pomoč
○
○
uradna MySQL dokumentacija: http://dev.mysql.com/doc/
StackOverflow
● kontakt
○
[email protected]