Delavnica MySQL
Transcription
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 ○ vid.podpecan@ijs.si