70
JU MJEŠOVITA SREDNJA ELEKTROTEHNIČKA ŠKOLSKA GODINA ŠKOLA TUZLA 2011./2012. MATURSKI RAD Predmet: Baze Podataka Tema: Optimizacija baze podataka korištenjem indeksa u MySQL-u sa primjenom na bazu podataka Rent-a-car

Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

Embed Size (px)

DESCRIPTION

Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

Citation preview

Page 1: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

JU MJEŠOVITA SREDNJA ELEKTROTEHNIČKA ŠKOLSKA GODINA ŠKOLA TUZLA 2011./2012.

MATURSKI RADPredmet: Baze Podataka

Tema: Optimizacija baze podataka korištenjem indeksa u MySQL-u sa primjenom na bazu podataka Rent-a-car

MENTOR: UČENIK: Selma Krajinović, dipl. ing. elektrotehnike Almin Karić

Razred: IVT1

TUZLA, maj, 2012.god.

Page 2: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

Sadržaj

1. UVOD....................................................................................................................................1

2. DEFINISANJE PROJEKTNOG ZADATKA........................................................................2

2.1 Profil klijenta...................................................................................................................2

2.2 Problemi klijenta..............................................................................................................2

2.3 Zahtjevi klijenta...............................................................................................................2

3. PROJEKTOVANJE BAZE PODATAKA – RENT-A-CAR................................................3

3.1 Analiza potreba................................................................................................................3

3.1.1.Upoznavanje sa opštim osobinama dijela realnosti...............................................3

3.1.2.Definisanje ciljeva, projektnog zadatka, uslova i opsega sistema.........................4

3.1.3.Definisanje radnih procesa....................................................................................8

3.2.Izrada konceptualnog modela podataka...........................................................................9

3.2.1. Identifikovanje podataka i veza između entiteta...................................................9

3.2.2. Izrada ER dijagrama pomoću alata MySQL Workbench....................................15

3.2.3. Izrada relacionog modela.....................................................................................16

3.2.4. Izrada testnih podataka u C++.............................................................................22

3.2.5.Prilozi...................................................................................................................22

4. INDEKSI..............................................................................................................................23

4.1. Šta su indeksi?...............................................................................................................23

4.1.1. Klasterovani i neklasterovani indeks..................................................................23

4.1.2. Kreiranje indeksa................................................................................................23

4.1.3. B-stablo..............................................................................................................24

4.1.4. Operacije nad B-stablom....................................................................................25

4.2. Problemi sa brzinom pristupa podacima.......................................................................26

4.2.1.Faktori koji utiču na performanse........................................................................26

4.2.2.Optimizacija MySQL servera..............................................................................27

4.2.3.Optimizacija SQL upita.......................................................................................28

5. IMPLEMENTACIJA INDEKSA NA BAZU PODATAKA – RANT-A-CAR..................30

5.1.Uticaj indeksa na performanse.......................................................................................30

5.2. Implementacija indeksa u MySQL................................................................................36

5.2.1.Dodavanje indeksa u tabeli „privatno_lice“........................................................36

5.2.2.Dodavanje indeksa u tabeli „radniik“..................................................................36

5.2.3.Dodavanje indeksa u tabeli „pravno_lice“..........................................................36

5.2.4.Dodavanje indeksa u tabeli „vozilo“...................................................................37

5.2.5.Dodavanje indeksa u tabeli „rezervacija“............................................................37

5.2.6.Skripta za dodavanje indeksa..............................................................................38

6. ZAKLJUČAK......................................................................................................................39

7. LITERATURA.....................................................................................................................40

Page 3: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

1. Uvod

Cilj ovog rada je kreiranje baze podataka za rent-a-car kompaniju po novim zahtjevima. Osim osnovnog kreiranja baze podataka u radu se nalazi i rješenje za probleme sa postojećom bazom podataka kao i implementiranje novih zahtjeva i bonusa koje traži kompanija.

Osim samog kreiranja baze podataka, u ovom radu se nalazi način na koji će se uspostaviti veza između poslovnica, objašnjenje za VPN.

Jedan od glavnih problema koje je imala rent-a-car kompanija ranije je spor pristup podacima. S obzirom na veliku količinu podataka, MySQL bazi podatka je potrebno veliko vrijeme za odgovor na neki od upita. Glavni cilj ovog rada je rješavanje tog problema s tim da se i dalje koristi MySQL baza.

Problem loših performansi u MySQL-u se može riješiti dodavanjem indeksa u odgovarajuće tabele na odgovarajuća mjesta. Indekse je potrebno dodati u tabele koje će se najviše pretraživati i koje imaju najveći broj zapisa.

Za testiranje velikog broja podataka napisane su C++ skripte za generisanje tih podataka koje se nalaze u prilogu maturskog rada. Osim samih podataka napisane su i SQL skripte za upis tih podataka koje se također nalaze u prilogu.

U ovom radu je urađena analiza sa indeksima i bez indeksa na SQL upitima koji koriste dvije ili više tabela sa najvećom količinom podataka. Ova analiza će se raditi u MySQL Workbench alatu tako da su rezlutati prikazani u slikama.

Struktura maturskog rada je sljedeća:

Definisanje projektnog zadatka (analiza o potrebama klijenta) Projektovanje baze podataka – rent-a-car Indeksi (šta su indeksi i šta se još može uraditi za optimizaciju samog SQL

servera) Implementacija indeksa na bazu podataka – rant-a-car (implementacija i uticaj

indeksa na ovu bazu podataka)

1

Page 4: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

2. Definisanje projektnog zadatka

2.1 Profil klijenta

Kompanija za iznajmljivanje vozila posluje u skladu sa sljedećim pravilima:

- djeluje na teritoriji više zemalja, - iznajmljuje vozila iz slijedećih kategorija: putnička vozila, teretna vozila- vozila iznajmljuje privatnim i pravnim licima (drugim kompanijama)- omogućava online kreiranje ponuda i rezervacija

Kompanija već koristi računarsku podršku za obavljanje svog posla, ali se suočava sa problemima koje nameću novi zahtjevi tržišta a koji postojeći sistem ne može ispuniti. Za potrebe ovog rada koristiti www prezentaciju kompanije Bugget.ba

2.2 Problemi klijenta

Neki od problema sa kojima se suočava tokom rada sa postojećim sistemom evidencije podataka:

- pri fakturisanju usluge iznajmljivanja vozila postoji potreba da se cijena usluge obračunava različito za radne dane i dane vikenda, - zbog velike konkurencije postoji potreba da se privuku korisnici, tako de im se

odobrava bonus (popust) na pojedine usluge, ukoliko su registrovani korsnici koji su ranijim iznjamljivanjima stekli povlastice

2.3 Zahtjevi klijenta

Potrebno je izgraditi bazu podataka koja će biti podrška za rad kompanije koja se bavi iznajmljivanjem vozila. Sistem obavezno mora da omogući:

- uspostavljanje centralne baze podataka dostupne svim agencijama kompanije za iznajmljivanje vozila

- Upotreba razlicitih šifarnika (kategorija vozila, vozilo, agencija, korisnici – privatna lica, korisnici – pravna lica)

- Evidenciju cjenovnika najma vozila po različitim kategorijama vozila i danima u sedmici

- Evidencija podataka o najmu vozila- Izračunavanje cijene najma vozila za potrebe slanje ponuda korisnicima- Kreiranje online ponuda i rezervacija za iznajmljivanje vozila, sa pregledom

raspoloživosti vozila po lokaciji, tipu vozila i datumu- Pregled podataka iz baze podataka po različitim kriterijima, i to:

Pregled izdatih / slobodnih vozila po tipu vozila, mjestu raspoloživosti i datumu

Uvid u istoriju iznajmljivanja vozila za odabranog korsnika firmu ili privatno lice

Pregled vozila čija registracija ističe u narednih mjesec dana

2

Page 5: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

3. Projektovanje baze podataka – rent-a-car

3.1 Analiza potreba

3.1.1. Upoznavanje sa opštim osobinama dijela realnosti

Čime se firma bavi?

Rent-A-Car kompanija se bavi iznajmljivanjem vozila za kratke vremenske periode uz određenu cijenu. Ova kompanija je sastavljena od međusobno povezanih poslovnica što omogućava korisnicima da vrate vozila na različitim lokacijama i odlikuje se sljedećim osobinama:

djeluje na teritoriji više zemalja, iznajmljuje vozila iz slijedećih kategorija: putnička vozila, teretna vozila vozila iznajmljuje privatnim i pravnim licima (drugim kompanijama) omogućava online kreiranje ponuda i rezervacija

Prilikom iznajmljivanja vozila u cijenu se uključuje:

osiguranje vozila kasko osiguranje vozila osiguranje vozača i putnika neograničena kilometraža osiguranje protiv krađe porez PDV po potrebi sjedalica za dijete od 1 mjesec do 7 godina.     

Ponudu kompanije karakterišu najpoznatiji svjetski brendovi, čime se osigurava ugodnost i sigurnost korisnika. Brendovi koje koristi kompanija su:

Audi Renault Mercedes-Benz Volkswagen Opel i dr.

Organizacija firme?

Firma je organizovana na taj način da djeluje na teritorij više država, također u jednoj državi djeluje na teritorij gradova i aerodroma. Neke od država na kojima firma djeluje su:

Bosna i Hercegovina Hrvatska Srbija Njemačka Belgija i dr.

Rezervacije za vozila se mogu kreirati online ili dolaskom u poslovnicu. Prilikom kreiranja rezervacije potrebno je odabrati državu, poslovnicu, datum i vrijeme preuzimanja i vraćanja vozila. Nakon što su unešene informacije o preuzimanju i vraćanju vozila, potrebno je odabrati jedno od ponuđenih vozila. Vozilo se može preuzeti u jednoj poslovnici i vratiti u drugoj.

3

Page 6: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

Rezultati poslovanja?

Za rezultate poslovanja spremaju se podaci o ostvarenoj zaradi za određeno vozilo, koji se modeli najviše iznajmljuju, vremenski period kada se vozila najviše iznajmljuju.

Kompanija koristi postojeći softver, međutim zbog novih zahtjeva na tržištu, pojavili su se određeni problemi poput:

Različit obračun cijena za radne dane i za vikend Popust za stalne korisnike na pojedine usluge Popust za izajmljivanje vozila na više od 5 dana

3.1.2. Definisanje ciljeva, projektnog zadatka, uslova i opsega sistema

Definisanje ciljeva

Cilj je razlog, ili vjerovatnije razlozi, zbog kojih se projekat pravi. Pri tome treba razlikovati pojmove „cilj“ i „projektni zadatak“. Cilj projekta baze podataka za Rent-a-car definiše se odgovaranjem na sljedeća pitanja:

Zbog čega je potrebna nova baza podataka za Rent-A-Car kompaniju? 

Kompanija već koristi postojeći softver ali zbog sve veće konkurencije i novih zahtjeva na tržištu, javljaju se se problemi. Problemi kod postojećeg softvera su sljedeći:

pri fakturisanju usluge iznajmljivanja vozila postoji potreba da se cijena usluge obračunava različito za radne dane i dane vikenda,

zbog velike konkurencije postoji potreba da se privuku korisnici, tako de im se odobrava bonus (popust) na pojedine usluge, ukoliko su registrovani korsnici koji su ranijim iznjamljivanjima stekli povlastice

Stoga kompanija zahtijeva novu bazu podataka koja će omogućiti da se riješe postojeći problemi.

Koji su to novi zahtjevi tržišta?

Novi zahtjevi tržišta su dodatne usluge koje kompanija nudi da bi privukla svoje kupce. Neki od zahtjeva tržišta:

poseban popust za dugoročne najmove  poseban popust za stalne mušterije  najam vozila sa šoferom  u slučaju nezgode vozilo može biti zamijenjeno  dostava i prihvat vozila 

Kakvi će se bonusi koristiti?

Bonusi će se koristiti na pojedine usluge u vidu popusta za stalne korisnike (članovi kluba korisnika) i za V.I.P. korisnike. Također bonus se može ostvariti za dugoročne najmove.

4

Page 7: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

Na koje usluge će se odnositi bonusi?

Bonusi, odnosno popusti će se odnositi na cijenu iznajmljivanja vozila za stalne korisnike i za dugoročne najmove (u procentima). Osim cijene iznamljivanja za stalne korisnike će biti popust i na iznajmljivanje GPS uređaja i najma vozila sa šoferom.

Definisanje projektnog zadatka

U bazi se evidentira kategorija vozila, na osnovu koje se formira cijena iznajmljivanja. Sva vozila evidentiraju se u slijedeće kategorije:

- Putničko vozilo A – mala vozila do 1400 kubika

- Putničko vozilo B – srednja vozila do 2000 kubika

- Putničko vozilo C - ostala putnička vozila

- Putničko vozilo D - vozila za prevoz registrovana za prevoz vise od 6 putnika

- Teretno vozilo A – vozilo nosivosti do 5t

- Teretno vozilo B – ostala teretna vozila

Za svaku od kategorija evidentira se cjenovnik, koji sadrži slijedeće podatke

- Dnevne cijena najma za radni dan

- Dnevna cijena najma za dane vikenda

- Dnevna cijena najma za najam vozila preko 5 dana

- Maksimalan broj kilometara po danu

- Datum od kada važi cjenovnik

- Datum do kada važi cjenovnik

- Koeficijent za koji se cijena uvećava ako se prekorači maksimalan broj kilometara po danu najma (ako je npr. Koeficijent 1.2, dnevna cijena je 100 KM i maksimalan broj kilometara po danu je 500 km, a vozilo je bilo iznajmljeno 5 radnih dana dana i ukupno je prešlo 3000 km, tada je cijena najma (5*100)*1.2 KM)

- Tip cjenovnika (A, B i C): prilikom iznajmljivanja vozila operater može primjeniti 3 različite kategorije cijena, u ovisnost i samom korisniku, čime se nekim korisnicima omogućava popust:

o ako su V.I.P korisnici primjenjuje se najpovoljniji, cjenovnik A

o Ako se iznajmljuje članovima kluba korisnika, primjenjuje se cjenovnik B

o Za ostale, primjenjuje se najskluplji cjenovnik C

Za svako vozilo evidentiraju se slijedeći podaci:

- Marka

- Tip

- Godina proizvodnje

- Registarke oznake

- Datum do kojeg važi registracija

- Mjesto registracije

- Država registracije

- Kategorija

5

Page 8: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

Za vozila iz kategorije putnička vozila dodatno se evidentiraju slijedeći podaci:

- Broj sjedišta

- Broj vrata

- Broj putnika

- Kapacitet prtljažnika (litara)

- Automatski klima uređaj (da/ne)

Za vozila iz kategorije teretna vozila dodatno se evidentiraju slijedeći podaci:

- Nosivost

- Težina praznog vozila

- Prikolica (da/ne)

- Nosivost prikolice

Za agencije evidentirati

- Naziv

- Sjedište, adresa, ulica

- Sjedište, adresa, broj

- Sjedište, adresa, mjesto

- Sjedište, adresa, poštanski broj

- Sjedište, adresa, država

- Broj telefona

- Broj telefaxa

- Email

- Kontakt osoba

Za korisnika privatno lice evidnetirati

- Prezime

- Ime

- Adresa, ulica

- Adresa, kućni broj

- Adresa, grad

- Adresa, poštanski broj

- Adresa, država

- Broj telefona

- Email

- Broj pasoša

- Broj kreditne kartice

- Tip kreditne kartice

- Članstvo u klubu korisnika ove rent-a-car kompanije (da/ne)

Za korisnika pravno lice evidentirati

- Naziv firme

- Sjedište, Adresa, ulica

6

Page 9: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

- Sjedište, Adresa, kućni broj

- Sjedište, Adresa, grad

- Sjedište, Adresa, poštanski broj

- Sjedište, Adresa, država

- Broj telefona

- Broj telefaxa

- Email

- Poreski broj

- Naziv poslovne banke

- Broj računa u banci

- Kontakt osoba, prezime ii me

- Članstvo u klubu korisnika ove rent-a-car kompanije (da/ne)

Definisanje uslova i opsega sistema

Zbog činjenice da sistem radi u više država potreban je pristup internetu kako bi se mogli međusobno povezati računari. Računari će biti povezani na VPN (Virtual Private Network) mreži.Virtuelna privatna mreža (Virtual Private Network – VPN) je privatna komunikaciona mreža koja se koristi za komunikaciju u okviru javne mreže. Transport VPN paketa podataka odvija se preko javne mreže (npr. Internet) korišćenjem standardnih komunikacionih protokola. VPN omogućava korisnicima na razdvojenim lokacijama da preko javne mreže jednostavno održavaju zaštićenu komunikaciju. Virtual Private Network software omogućava privatnu komunikaciju preko računarske tehnologije „tuneliranje“. VPN software uključuje aplikacije za klijente, servere i održavanje. Cilj VPN software je da umreži udaljene računare (ili LAN mreže) putem Interneta, kako bi se izbjegao skupi sistem zakupljenih ili kupljenih linija. U ovom sistemu koristi se centralizirana baza podataka, tj. koristi se jedna baza podatka za državu. VPN će omogućiti povezivanje svih poslovnica poslovnica koje pripadaju sistemu (kao npr. poslovnice iz druge države) na tu bazu podatka. Na ovaj način moguće je da sve poslovnice imaju pristup svim bazama podatka u sistemu ove kompanije rent-a-car, čime se omogućuje preuzimanje vozila u jednoj državi i vraćanje u drugoj. Osim poslovnica, svim bazama podataka ima pristup i web site na kojem je omogućeno kreiranje online rezervacija.

Opseg sistema u jednoj državi ovisi o broju poslovnica u toj državi. Za jednu poslovnicu se očekuje da će u toku jedne godine imati:

10 agencija: očekivani porast agencija je 2% godišnje 20 pravnih lica: očekivani porast pravnih lica je 10% godišnje 100 privatnih lica: očekivani porast privatnih lica je 10% godišnje

U bazi podataka za jednu poslovnicu se nalaze 1 ili 2 administratora koja održavaju bazu, imaju pristup cijeloj bazi, svim tabelama u njoj i mogu dodavati nove tabele i brisati postojeće. Osim administratora, baza će sadržavati uposlenike firme koji će imati različit pristup, korisnici su:

1 direktor: ima pristup podacima iz svih tabela i može mijenjati podatke iz svih tabela ali ne može dodavati nove ili brisati postojeće.

2 poslovođe: ima pristup podacima iz svih tabela, međutim ne može mijenjati podatke iz tabele “cjenovnik” dok podatke iz ostalih tabela može mijenjati.

10 radnika: ima pristup podacima iz svih tabela, može mijenjati podatke iz tabela “agencija”, “privatno lice”, pravno lice” dok za ostale ne može.

7

Page 10: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

3.1.3. Definisanje radnih procesa

Svrha većine sistema koji rade sa bazama podataka je podrška obavljanju jedne ili više aktivnosti dijela realnosti (preduzeća, ustanove, organizacije i sl) za koji se baza podataka pravi. Te aktivnosti su radni procesi koje će sistem podržavati. Radni proces je skup jednog ili više pojedinačnih poslova koji zajedno čine aktivnost koja se obavlja u nekoj organizaciji.

Radni procesi koji će se koristit u rent-a-car bazi su:

Registracija korisnika Iznajmljivanje vozila

Posao je pojedinačna akcija, tj. korak tokom odvijanja radnog procesa. Radni procesi se sastoje od poslova. Radni proces „registracija korisnika“ sastoji se od slijedećih poslova:

Prikupljanje podataka Provjera da li taj korisnik postoji u bazi Upisivanje podataka u bazu Određivanje da li su korisnici V.I.P. ili ostali.

Slika 1. UML dijagram za radni proces registracija korisnika

Radni proces „iznajmljivanje vozila“ se sastoji od slijedećih poslova:

Pristup podacima korisnika Kreiranje narudžbe (izbor vozila, određivanje mjesta i vremena preuzimanja i

vraćanja vozila) Određivanje cijene i načina plaćanja Izdavanje dokumenta na osnovu kojeg korisnik može preuzeti vozilo

8

Page 11: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

Slika 2. UML dijagram za radni proces iznajmljivanje vozila

3.2. Izrada konceptualnog modela podataka

3.2.1. Identifikovanje podataka i veza između entiteta

Slika 3. ER Dijagram

U kakvoj je vezi entitet sa realnošću preduzeća?

- Entitet radnik omogućava pohranu informacija o ličnih podataka osobe kao i funkcije koje obavlja u kompaniji.

- Entitet privatno lice omogućava pohranjivanje ličnih podataka o kupcima, koje su potrebne kompaniji.

- Entitet pravno lice omogućava pohranjivanje fizičkih informacija o firmi koja je klijent ove kompanije, kao i informacije za kontaktiranje firme.

- Entitet agencija omogućava pohranjivanje fizičkih informacija o agenciji i informacija koje su potrebne za kontakt agencije

- Entitet cjenovnik omogućava pohranjivanje podataka o cjenovniku za različite uslove, na osnovu kojih se računa ukupna cijena iznajmljivanja vozila.

- Entitet vozilo omogućava pohranjivanje informacija o fizičkim osobinama vozila, kao i informacije o registraciji.

- Entitet putnicko vozilo omogućava pohranjivanja informacija o fizičkim osobinama putničkog vozila

- Entitet teretno vozilo omogućava pohranjivanje informacija o fizičkim osobinama teretnog vozila.

- Entitet rezervacija omogućava pohranu podataka koji se koriste prilikom rezervacije.

- Entitet kategorija omogućava pohranjivanje informacija o opisu kategorije vozila.

9

Page 12: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

Radni procesi koji utiču na entitet

- Podaci pohranjeni u entitetu „privatno lice“ i „pravno lice“ koriste se u radnom procesu „registracija korisnika“ na taj način što se provjerava da li ovaj entitet sadrži primjerak (ili objekat) sa istim osobinama kao korisnik koji se želi registrovati. Ukoliko ne sadrži, u ovaj entiet se kreira novi objakt i upisuju podaci o njemu.

- Podaci pohranjeni u entitetima „privatno lice“ i „pravno lice“ se također koristi u radnom procesu „iznajmljivanje vozila“. Određeni podaci iz ovih entiteta se koriste u radnom procesu.

- Entitet “rezervacija” se koristi u radnom procesu “iznajmljivanje vozila”. U ovom radnom procesu, podaci se upisuju u entitet “rezervacija”

- Podaci pohranjeni u entitet “cjenovnik” koriste se u radnom procesu “iznajmljivanje vozila”. Podaci iz ovog entiteta koriste se za računanje cijene za iznajmljeno vozilo.

- Podaci pohranjeni u entitet “vozilo” koriste se u radnom procesu “iznajmljivanje vozila”. Na osnovu ovih podataka moguće je odabrati željeno vozilo.

Interakcija između entiteta

- Veza vozila – putnička vozila (N:1) i vozila – teretna vozila (N:1), omogućava da se označe kojoj vrsti određena vozila pripdaju, u ovoj vezi moguće je da više vozila pripada putničkim ili teretnim vozilima

- Vezom cjevnovnik – kategorija (N:1), moguće je odabrati željeni cjenovnik za određenu kategoriju

- Veza kategorija – vozilo (1:N), vozilo smješta u određenu kategoriju. Jedno vozilo može biti u samo jednoj kategoriji, dok se jedna kategorija može odnositi na više vozila.

- Vezom cjenovnik – rezervacija (1:N), moguće je koristiti podatke iz entiteta cjenovnik i na taj način izračunati ukupnu cijenu za iznajmljivanje vozila.

- Veza vozilo – rezervacija (1:N), omogućava da se rezerviše određeno vozilo.- Veza rezervacija – privatno lice (N:1) i rezervacija – pravno lice (N:1), omogućava

da se odredi koji je korisnik kreirao rezervaciju.- Veza radnik – privatno lice (1:N) i radnik – pravno lice (1:N), omogućava da se

odredi koji je radnik kreirao određenog korisnika.- Veza agencija – radnik (1:N); omogućava da se odredi u kojoj agenciji radi taj

radnik.- Veza agencija – vozilo (1:N), određuje u kojoj se poslovnici trenutno nalazi vozilo

Poslovna pravila i uslovi koji se odnose na taj entitet

Prilikom unosa podataka u bazu podataka postoje određena pravila kao što su:

- Podaci o vozilu ne mogu se unijeti prije nego što se unesu podaci u entitete “kategorija”, “putnicka_vozila” i “teretna_vozila”

- Podaci u entitet “cjenovnik” ne mogu se unijeti prije nego što se unesu podaci u entiet “kategorija”.

- Podaci u entitet “radnik” ne mogu se unijeti prijen nego što se unesu podaci u entitet “agencija”.

- Podaci u entitete “poslovno_lice” i “privatno_lice” ne mogu se unijeti prije nego što se unesu podaci u entitet “radnik”.

- Podaci u entitet “rezervacija” ne mogu se unijeti prije nego što se unesu podaci u entiete “cjenovnik”, “vozilo”, “privatno_lice” i “pravno_lice”

10

Page 13: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

11

Page 14: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

Atributi entiteta

Tabela 1. Objekat kategorija

Naziv atributa Tip podatka Obavezno polje Primarni ključ OpisID Integer da da Primarni ključKategorija VARCHAR (45) da ne Oznaka kategorijeDetalji VARCHAR (150) ne ne Opis kategorije

Tabela 2. Objekat cjenovnik

Naziv atributa Tip podatka Obavezno polje Primarni ključ OpisID Integer da da Primarni ključKategorija_id Integer da ne Strani ključCijena_radni_dan Decimal (10,2) da ne Cijene za radni danCijena_vikend Decmial (10,2) da ne Cijena za vikendVise_dana Decimal (10,2) da ne Cijena

iznajmljivanja za više dana

Max_kilometara Integer ne ne Makismalan broj kilometara po danu

Pocetni_datum DATE da ne Datum pocetka važenja cjenovnika

Krajnji_datum DATE ne ne Datom do kojeg vazi cjenovnik

Koeficijent Decimal (3,2) ne ne Koeficijent za obračunavanje

Tip Pobrojani da ne Vrijednosti: VIP, članstvo, obični

12

Page 15: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

Tabela3. Objekat vozilo

Naziv atributa Tip podatka Obavezno polje Primarni ključ OpisID Integer da da Primarni ključKategorija_id Integer da ne Strani ključPutnicka_vozila Integer ne ne Strani ključTeretna_vozila Integer ne ne Strani ključAgencija_id Integer da ne Strani ključMarka VARCHAR (45) da ne Marka vozilaTip VARCHAR (45) da ne Tip vozilaGodina_proizvodnje Year da neReg_oznake VARCHAR (10) da ne Registarske

oznakeReg_mjesto VARCHAR (45) da ne Mjesto

registracijeReg_drzava VARCHAR (45) da ne Država

registracijeDatum_isteka Date da ne Isek registracijeZadnje_servisiranje Date da neSlika1 VARCHAR(150) ne ne Slika vozilaSlika2 VARCHAR(150) ne ne Slika vozilaSlika3 VARCHAR(150) ne ne Slika vozila

Tabela 4. Objekat putnicka_vozila

Naziv atributa Tip podatka Obavezno polje Primarni ključ OpisID Integer da da Primarni ključsjedista Integer da ne Broj sjedištavrata Integer da ne Broj vrataputnici Integer da ne Broj putnikprtljaznik Integer da ne Kapacitet

prtljažnikaklima Bool da ne DA ili NE

Tabela 5. Objekat teretna_vozila

Naziv atributa Tip podatka Obavezno polje Primarni ključ OpisID Integer da da Primarni ključnosivost Integer da ne Nosivost vozilatezina integer da ne Težina praznog

vozilaprikolica bool da ne DA ili NEPrikolica_nosivost

Integer da ne

13

Page 16: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

Tabela 6. Objekat rezervacija

Naziv atributa Tip podatka Obavezno polje Primarni ključ OpisID Integer da da Primarni ključCjenovnik_id Integer da ne Strani ključVozilo_id Integer da ne Strani ključPrivatno_lice_id

Integer ne ne Strani ključ

Pravno_lice_id Integer ne ne Strani ključKreiranje DATE da ne Datum kreiranjaPodizanje DATE da ne Datum podizanja

vozilaVracanje DATE da ne Datum vraćanja

vozilaCijena Decimal (10,2) da ne Ukupna cijena

iznamljivanja.Broj_dana Integer da ne Broj dana za

iznajmljivanje

Tabela 7. Objekat privatno_lice

Naziv atributa Tip podatka Obavezno polje Primarni ključ OpisID Integer da da Primarni ključRadnik_id Integer da ne Strani ključPrezime VARCHAR (45) da neIme VARCHAR (45) da neUsername VARCHAR (45) da ne Unique poljePassword VARCHAR (45) ne ne Unique poljeZadnja_posjeta DATETIME ne neUlica VARCHAR (45) ne ne Naziv uliceKucni_broj VARCHAR (5) ne ne Broj kuće ili stanaGrad VARCHAR (45) ne nePostanski_broj Integer ne neDrzava VARCHAR (45) ne neBroj_kartice VARCHAR (45) ne neTip_kartice VARCHAR (45) ne neemail VARCHAR (80) ne neBroj_pasosa VARCHAR (45) da neClanstvo Bool ne ne DA ili NE

14

Page 17: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

Tabela 8. Objekat pravno_lice

Naziv atributa Tip podatka Obavezno polje Primarni ključ OpisID Integer da da Primarni ključRadnik_id Integer da ne Strani ključNaziv VARCHAR (45) da ne Naziv firmeUlica VARCHAR (45) da ne Naziv uliceKucni_broj VARCHAR (5) ne ne Broj kuće ili stanaGrad VARCHAR (45) da nePostanski_broj Integer da neDrzava VARCHAR (45) ne neBroj_telefona VARCHAR (20) ne neBroj_faxa VARCHAR (20) ne neEmail VARCHAR (80) ne nePoreski_broj VARCHAR (45) ne neNaziv_banke VARCHAR (45) ne neBroj_racuna VARCHAR (15) ne neKontakt_osoba VARCHAR (45) ne neClanstvo Bool ne ne DA ili NE

Tabela 9. Objekat radnik

Naziv atributa Tip podatka Obavezno polje Primarni ključ OpisID Integer da da Primarni ključAgencija_id Integer da ne Strani ključIme VARCHAR (45) da nePrezime VARCHAR (45) da neUsername VARCHAR (45) da ne Unique poljePassword VARCHAR (45) ne ne Unique poljeZadnja_posjeta DATETIME ne neUlica VARCHAR (45) ne ne Naziv uliceKucni_broj VARCHAR (5) ne ne Broj kuće ili stanaPostanski_broj Integer ne neDrzava VARCHAR (45) ne neemail VARCHAR (80) ne nePotpisivanje ugovora

DATE da ne

Istek_ugovora DATE ne nePlata Decimal (10,2) da ne Mjesečna plataJMBG VARCHAR (13) da neBroj_telefona VARCHAR (20) ne neFunkcija Pobrojani da ne Vrijednosti:

direktor, poslovođa, radnik

15

Page 18: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

Tabela 10. Objekat agencija

Naziv atributa Tip podatka Obavezno polje Primarni ključ OpisID Integer da da Primarni ključNaziv VARCHAR (45) ne ne Naziv agencijeUlica VARCHAR (45) da ne Naziv uliceKucni_broj VARCHAR (5) ne ne Broj kuće ili stanaGrad VARCHAR (45) da nePostanski_broj Integer da neDrzava VARCHAR (45) ne neBroj_telefona VARCHAR (20) ne neEmail VARCHAR (80) ne neKontakt_osoba VARCHAR (45) ne ne

3.2.2. Izrada ER dijagrama pomoću alata MySQL Workbench

Slika 4. ER dijagram u MySQL Workbech

16

Page 19: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

Pravila za imenovanje atributa

Prilikom imenovanja atributa u MySQL Workbench alatu, korišteni su isti nazivi kao što je opisano u tabelama u dijelu „atributi entiteta“ ovog dokumenta. Atributi su imenovani jednostavnim nazivima koji asociraju na određene podatke koji opisuju taj objekati tj. entitet.

Pravila za primarne i strane ključeve

U svim tabelama primarni ključevi su označeni sa „id“, dok su strani ključevi označeni sa „naziv tabele_id“. Svaki primarni ključ u tabeli (id) je autoincrement što znači da ukoliko se ne unese vrijednost za ovo polje, DBMS automatski unosi podatke za „id“

3.2.3. Izrada relacionog modela

SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';

CREATE SCHEMA IF NOT EXISTS mtr DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci ;USE mtr ;

-- ------------------------------------------------------- Table kategorija-- -----------------------------------------------------DROP TABLE IF EXISTS kategorija ;

CREATE TABLE IF NOT EXISTS kategorija ( id INT NOT NULL AUTO_INCREMENT , kategorija VARCHAR(45) NOT NULL , detalji VARCHAR(255) NULL , PRIMARY KEY (id) )ENGINE = InnoDB;

-- ------------------------------------------------------- Table putnicka_vozila-- -----------------------------------------------------DROP TABLE IF EXISTS putnicka_vozila ;

CREATE TABLE IF NOT EXISTS putnicka_vozila ( id INT NOT NULL AUTO_INCREMENT , sjedista INT NOT NULL , vrata INT NOT NULL , putnici INT NOT NULL , prtljaznik INT NULL , klima TINYINT(1) NULL , PRIMARY KEY (id) )ENGINE = InnoDB;

17

Page 20: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

-- ------------------------------------------------------- Table teretna_vozila-- -----------------------------------------------------DROP TABLE IF EXISTS teretna_vozila ;

CREATE TABLE IF NOT EXISTS teretna_vozila ( id INT NOT NULL AUTO_INCREMENT , nosivost INT NOT NULL , tezina INT NOT NULL , prikolica TINYINT(1) NULL , prikolica_nosivost INT NULL , PRIMARY KEY (id) )ENGINE = InnoDB;

-- ------------------------------------------------------- Table cjenovnik-- -----------------------------------------------------DROP TABLE IF EXISTS cjenovnik ;

CREATE TABLE IF NOT EXISTS cjenovnik ( id INT NOT NULL AUTO_INCREMENT , cijena_radni_dan DECIMAL(10,2) NOT NULL , cijena_vikend DECIMAL(10,2) NOT NULL , vise_dana DECIMAL(10,2) NOT NULL , max_kilometara INT NULL , pocetni_datum DATE NOT NULL , krajnji_datum DATE NULL , koeficijent DECIMAL(3,2) NULL , tip ENUM('VIP', 'clanstvo', 'obicni') NOT NULL , kategorija_id INT NOT NULL , PRIMARY KEY (id) , INDEX fk_cjenovnik_kategorija1 (kategorija_id ASC) , CONSTRAINT fk_cjenovnik_kategorija1 FOREIGN KEY (kategorija_id ) REFERENCES kategorija (id ) ON DELETE NO ACTION ON UPDATE NO ACTION)ENGINE = InnoDB;

-- ------------------------------------------------------- Table agencija-- -----------------------------------------------------DROP TABLE IF EXISTS agencija ;

CREATE TABLE IF NOT EXISTS agencija ( id INT NOT NULL AUTO_INCREMENT , naziv VARCHAR(45) NULL , ulica VARCHAR(45) NOT NULL , kucni_broj VARCHAR(5) NULL , grad VARCHAR(45) NOT NULL ,

18

Page 21: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

postanski_broj INT NOT NULL , drzava VARCHAR(45) NULL , broj_telefona VARCHAR(20) NULL , email VARCHAR(80) NULL , kontak_osoba VARCHAR(45) NULL , PRIMARY KEY (id) )ENGINE = InnoDB;

-- ------------------------------------------------------- Table vozilo-- -----------------------------------------------------DROP TABLE IF EXISTS vozilo ;

CREATE TABLE IF NOT EXISTS vozilo ( id INT NOT NULL AUTO_INCREMENT , marka VARCHAR(45) NOT NULL , tip VARCHAR(45) NOT NULL , godina_proizvodnje YEAR NOT NULL , reg_oznake VARCHAR(10) NOT NULL , reg_mjesto VARCHAR(45) NULL , reg_drzava VARCHAR(45) NULL , datum_isteka DATE NOT NULL , zadnje_servisiranje DATE NOT NULL , kategorija_id INT NOT NULL , putnicka_vozila_id INT NULL , teretna_vozila_id INT NULL , agencija_id INT NOT NULL , slika1 VARCHAR(150) NULL , slika2 VARCHAR(150) NULL , slika3 VARCHAR(150) NULL , PRIMARY KEY (id) , INDEX fk_vozilo_kategorija1 (kategorija_id ASC) , INDEX fk_vozilo_putnicka_vozila1 (putnicka_vozila_id ASC) , INDEX fk_vozilo_teretna_vozila1 (teretna_vozila_id ASC) , INDEX fk_vozilo_agencija1 (agencija_id ASC) , CONSTRAINT fk_vozilo_kategorija1 FOREIGN KEY (kategorija_id ) REFERENCES kategorija (id ) ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT fk_vozilo_putnicka_vozila1 FOREIGN KEY (putnicka_vozila_id ) REFERENCES putnicka_vozila (id ) ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT fk_vozilo_teretna_vozila1 FOREIGN KEY (teretna_vozila_id ) REFERENCES teretna_vozila (id ) ON DELETE NO ACTION ON UPDATE NO ACTION,

19

Page 22: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

CONSTRAINT fk_vozilo_agencija1 FOREIGN KEY (agencija_id ) REFERENCES agencija (id ) ON DELETE NO ACTION ON UPDATE NO ACTION)ENGINE = InnoDB;

-- ------------------------------------------------------- Table radnik-- -----------------------------------------------------DROP TABLE IF EXISTS radnik ;

CREATE TABLE IF NOT EXISTS radnik ( id INT NOT NULL AUTO_INCREMENT , ime VARCHAR(45) NOT NULL , prezime VARCHAR(45) NOT NULL , username VARCHAR(45) NOT NULL , password VARCHAR(45) NULL , zadnje_logovanje DATETIME NULL , ulica VARCHAR(45) NULL , kucni_broj VARCHAR(5) NULL , postanski_broj INT NULL , drzava VARCHAR(45) NULL , email VARCHAR(80) NULL , potpisivanje_ugovora DATE NOT NULL , istek_ugovora DATE NULL , plata DECIMAL(10,2) NOT NULL , JMBG VARCHAR(13) NOT NULL , broj_telefona VARCHAR(20) NULL , funkcija ENUM('radnik', 'poslovodja', 'direktor') NOT NULL , agencija_id INT NOT NULL , PRIMARY KEY (id) , INDEX fk_radnik_agencija1 (agencija_id ASC) , UNIQUE INDEX username_UNIQUE (username ASC) , CONSTRAINT fk_radnik_agencija1 FOREIGN KEY (agencija_id ) REFERENCES agencija (id ) ON DELETE NO ACTION ON UPDATE NO ACTION)ENGINE = InnoDB;

-- ------------------------------------------------------- Table privatno_lice-- -----------------------------------------------------DROP TABLE IF EXISTS privatno_lice ;

CREATE TABLE IF NOT EXISTS privatno_lice ( id INT NOT NULL AUTO_INCREMENT , ime VARCHAR(45) NOT NULL , prezime VARCHAR(45) NOT NULL ,

20

Page 23: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

username VARCHAR(45) NOT NULL , password VARCHAR(45) NULL , zadnja_posjeta DATETIME NULL , ulica VARCHAR(45) NULL , kucni_broj VARCHAR(5) NULL , grad VARCHAR(45) NULL , postanski_broj INT NULL , drzava VARCHAR(45) NULL , email VARCHAR(80) NULL , broj_pasosa VARCHAR(45) NOT NULL , broj_kartice VARCHAR(45) NULL , tip_kartice VARCHAR(45) NULL , clanstvo TINYINT(1) NULL , radnik_id INT NOT NULL , PRIMARY KEY (id) , INDEX fk_privatno_lice_radnik1 (radnik_id ASC) , UNIQUE INDEX username_UNIQUE (username ASC) , CONSTRAINT fk_privatno_lice_radnik1 FOREIGN KEY (radnik_id ) REFERENCES radnik (id ) ON DELETE NO ACTION ON UPDATE NO ACTION)ENGINE = InnoDB;

-- ------------------------------------------------------- Table pravno_lice-- -----------------------------------------------------DROP TABLE IF EXISTS pravno_lice ;

CREATE TABLE IF NOT EXISTS pravno_lice ( id INT NOT NULL AUTO_INCREMENT , naziv VARCHAR(45) NOT NULL , ulica VARCHAR(45) NOT NULL , kucni_broj VARCHAR(5) NULL , grad VARCHAR(45) NOT NULL , postanski_broj INT NOT NULL , drzava VARCHAR(45) NULL , broj_telefona VARCHAR(20) NULL , broj_faxa VARCHAR(20) NULL , email VARCHAR(80) NULL , poreski_broj VARCHAR(45) NULL , naziv_banke VARCHAR(45) NULL , broj_racuna VARCHAR(15) NULL , kontakt_osoba VARCHAR(80) NULL , clanstvo TINYINT(1) NULL , radnik_id INT NOT NULL , PRIMARY KEY (id) , INDEX fk_pravno_lice_radnik1 (radnik_id ASC) , CONSTRAINT fk_pravno_lice_radnik1 FOREIGN KEY (radnik_id )

21

Page 24: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

REFERENCES radnik (id ) ON DELETE NO ACTION ON UPDATE NO ACTION)ENGINE = InnoDB;

-- ------------------------------------------------------- Table rezervacija-- -----------------------------------------------------DROP TABLE IF EXISTS rezervacija ;

CREATE TABLE IF NOT EXISTS rezervacija ( id INT NOT NULL AUTO_INCREMENT , kreiranje DATE NOT NULL , podizanje DATE NOT NULL , vracanje DATE NOT NULL , cijena DECIMAL(10,2) NOT NULL , broj_dana INT NULL , cjenovnik_id INT NOT NULL , vozilo_id INT NOT NULL , privatno_lice_id INT NULL , pravno_lice_id INT NULL , PRIMARY KEY (id) , INDEX fk_rezervacija_cjenovnik1 (cjenovnik_id ASC) , INDEX fk_rezervacija_vozilo1 (vozilo_id ASC) , INDEX fk_rezervacija_privatno_lice1 (privatno_lice_id ASC) , INDEX fk_rezervacija_pravno_lice1 (pravno_lice_id ASC) , CONSTRAINT fk_rezervacija_cjenovnik1 FOREIGN KEY (cjenovnik_id ) REFERENCES cjenovnik (id ) ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT fk_rezervacija_vozilo1 FOREIGN KEY (vozilo_id ) REFERENCES vozilo (id ) ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT fk_rezervacija_privatno_lice1 FOREIGN KEY (privatno_lice_id ) REFERENCES privatno_lice (id ) ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT fk_rezervacija_pravno_lice1 FOREIGN KEY (pravno_lice_id ) REFERENCES pravno_lice (id ) ON DELETE NO ACTION ON UPDATE NO ACTION)ENGINE = InnoDB;SET SQL_MODE=@OLD_SQL_MODE;SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;

22

Page 25: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

3.2.4. Izrada testnih podataka u C++

U prilogu se nalaze C++ aplikacije koje kreiraju testne podatke. Za kreiranje podataka za radnika, privatno lice i pravno lice slučajnim izborom se biraju podaci iz datoteka imena.txt i prezimena.txt koji se postavljaju kao ime i prezime radnika, privatnog i pravnog lica. Zatim se slučajnim izborom bira adresa iz datoteke adresa.txt. Osim ovih podataka slučajnim izborom brojeva se postavlja potreban datum, username, JMBG i sl.

Za tebelu rezervacija se slučajnim izborom postavlja datum_kreiranja. Nakon toga se taj datum poveća za određeni broj dana (slučajni izbor) kako bi se dobio datum podizanja. Datum podizanja se također poveća za određeni broj dana (slučajni izbor) kako bi se dobio datum vraćanja

Atribut država se u tabelma gdje je to potrebno postavlja na osnovu odabranih gradova. Podaci za tabelu vozilo se generišu na taj način da se slučajnim izborom odaberu podaci iz datoteke audi_models.txt, bmw_models.txt, vw_models.txt. Ostali podaci u ovoj tabeli se generišu slučajnim izborom na osnovu određenog algoritma. Podaci u tabelama putnicko_vozilo i teretno_vozilo su generisani slučajnim brojevima (svi podaci u ovim tabelama su numerički tj. brojevi).

3.2.5. Prilozi

a. er_model.mwbb. er_dijagram.pdfc. create_database.sqld. sql skripte za kreiranje testnih podataka e. c++ kod za kreiranje skripti

23

Page 26: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

4. Indeksi

4.1. Šta su indeksi?

Indeksi su objekti šeme koji se koriste u sistemu baza podataka kako bi se ubrzalo pretraživanje podataka. Odgovarajuća upotreba indexa može pretvoriti tromu i nepredvidivu aplikaciju u vrlo odgovaran i visoko produktivan poslovni alat ali moguće je i obratno.

Indeks je ustvari B-stablo indeks (engl. B-tree index), u kome se podaci podaci koji nas intersuju locirani u osnivi indeksa, u okviru onoga što se naziva krajnji čvor. Ako postoji više od jednog krajnjeg čvora, sistem za upravljanje bazom podataka generiše čvorove grana (međučvor) da bi ukazao na krajnje čvorove. U okviru svakog krajnjeg čvora, nalazi se ključni podatak na osnovu kojeg je indeks izgrađen, kao i rowid (broj reda) roditeljskog reda originalne tabele.

Ukoliko ne postoji indeks, sistem tada pretražuje cijelu tabelu od početka do kraja dok ne pronađe odgovarajući podatak. Takvo pretraživanje je poznato pod imenom pretraživanje cijele tabele. Pomoću indeksa pretraživanje ne mora biti sekvencijalno ili neefikasno. Podaci se na ovaj način pretražuju po abecednom redoslijedu tako da nije potrebno čitanje svih blokova tabele. Na ovaj način indeksi mogu smanjiti broj I/O operacija skraćivanjem pristupnog puta podacima.

4.1.1. Klasterovani i neklasterovani indeks

Razlikuju se dvije vrste indeksa: klasterovani i neklasterovani.

Klasterovani indeks, na svom najnižem nivou (Leaf level) sadrži zapravo same podatke, dok neklasterovani indeks sadrži reference na prave podatke. Iz ovoga se zaključuje da neklasterovani indeks zahteva jedan korak više, kako bi se došlo do stvarnog podatka. Zato su neklasterovani indeksi nešto sporiji od klasterovanog. Klasterovani indeks se formira prema podacima.Također nije moguće postaviti više klasterovanih indeksa u okviru jedne tabele. Ovo pravilo ne važi i za neklasterovane indekse, kojih je moguće postaviti i više u okviru tabele.

4.1.2. Kreiranje indeksa

Indeks se kreira odvojeno i nezavistan je od tabele. Postoje dva načina kreiranja indeksa: automatski i manuelno.

Automatski: unique indeks se kreira automatski kada se definiše PRIMARY KEY ili UNIQUE ograničenje.

Manuelno: Korisnici mogu kreirati nejedinstvene indekse po kolonama da ubrzaju pristup podacima.

Prilikom indeksiranja, potrebno je voditi računa na koje će se kolone postaviti indeks, kako ne bi usporili radi cijelog sistema. Indeksi su u stanju da znatno ubrzaju pretragu, ali, njima se takođe pristupa i prilikom drugih intervencija na tabelama. Na primjer, izmjenama ili brisanju redova. Kada dođe do brisanja nekog reda, taj isti red mora biti obrisan i u indeksu. Isto važi i za izmenu ili dodavanje. To znači da se sam proces rukovanja ovim podacima usporava. Što više indeksiranih kolona u tabeli, toliko više usporenja uzrokovanih obradom indeksa prilikom rukovanja podacima te tabele. To objašnjava da indekse ne treba baš nasumično rasuti, već ih treba pozicionirati na „uska grla” u tabeli prilikom pretrage.

24

Page 27: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

Indeks se kreira ako:

Kolone sadrže širok rang vrijednosti Kolone sadrže velik broj null vrijednosti Jedna ili više kolona se često koriste u WHERE klauzuli ili join uslovu tabela je velika i očekuje se da većina upita pretražuje manje od 2 do 4 % redova

Obično se ne koriste indeksi ako:

Tabela je mala Kolone se ne koriste često kao uslov u upitima Najveći broj upita vraća više od 2 do 4 % redova Tabela (polja indeksa) se ažurira često Indeks kolone se koriste kao dio izraza

Function-Based indeksi

function-based indeks je indeks baziran na izrazima. Indeks izraz se gradi na osnovu kolona tabele, konstanti, SQL funkcija i user-

definisanih funkcija.

Indeks se kreira u MySQL na slijedeći način:

CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_imeON ime_tabele (indeks_ime_kolone,...)[tip_indeksa]

Gdje je:

indeks_ime_kolone: ime_kolone [(dužina)] [ASC | DESC]

tip_indeksa: USING {BTREE | HASH}

4.1.3. B-stablo

Stablo reda m je stablo u kome je izlazni red svakog čvora manji ili jednak m (svaki čvor ima najviše m sljedbenika). Svaki čvor sadrži određen broj ključeva; čvor sa k sljedbenika sadrži tačno k – 1 ključeva. Ako su ključevi i podstabla uređeni kao kod stabla pretrage, stablo reda m naziva se stablom pretrage reda m.

Posebno poželjna osobina stabla pretrage reda m, kada je u pitanju efikasnost njegovog pretraživanja, jeste balansiranost koja označava da je dužina puta od korjena do svakog lista jednaka.

Jedna specifična struktura balansiranog stabla, poznata kao B-stablo, poslužila je kao osnov za izgradnju niza struktura podataka koje se koriste u implementaciji indeksa.

Struktura specijalizovana za korišćenje na disku Čvorovi – blokovi fiksne veličine na disku – “stranice” Puno ključeva na jednoj stranici, puno sljedbenika, veliki red m – velika efikasnost

pristupa podacima na disku

B-stablo reda m je stablo pretrage reda m takvo da:

Svi listovi su na najnižem nivou (stablo je balansirano)

25

Page 28: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

Svi unutrašnji čvorovi (osim možda korena) imaju najmanje ceil (m / 2) (nepraznih) sledbenika.

Koreni čvor, ako nije list, ima najmanje 2 sljedbenika, a ako je istovremeno i list onda nema sljedbenika (i stablo se sastoji samo od tog jednog čvora)

Svaki list sadrži najmanje ceil(m / 2) - 1 ključeva

B-stablo je osnovna drvoidna indeksna struktura, koja sadrži podatke (ključeve tj. slogove) na svim nivoima. Popunjenost stranice min 50%, u proseku oko 70%. Modifikacije: B* stablo, B+ stablo, sa većom popunjenošču / razdvojenim indeksom od podataka / sekvencijalnošću nad podacima.

Slika 5. Primjer b-stabla

4.1.4. Operacije nad B-stablom

Pretraživanje

1. Neka je stranica N - korjena stranica2. Pretražujemo stranicu N na ključ Klj3. Ako je ključ Klj nađen, pretraživanje uspešno4. Inače,

- Ako je stranica N list, pretraživanje je neuspešno- Inače, naći među ključevima N.Kljucevi[0], N.Kljucevi[1], N.Kljucevi[2], … ,

N.Kljucevi[Br-1] najmanji ključ koji je veći od Klj; neka je to ključ N.Kljucevi[j]; N postaje stranica na koju pokazuje pokazivač N.Grane [j-1]; preći na korak 2.

Unošenje

Pretražiti B-stablo ključem unošenjaAko ključ nije nađen, pretraga je završena u listu1. Ako ima mjesta u listu, unijeti ključu list uz eventualna pomjeranja2. Ako je list pun, treba ga “pocjepati”:

2.1. oko polovine ključeva ostaje na starom listu2.2. oko polovine ključeva ide na novi list desno od postojećeg2.3. srednji ključ se “penje” u roditeljski čvor, pomeraju se ključevi i pokazivači

3. Ako u roditeljskom (unutrašnjem) čvoru nema mesta, i on se “cepa”: 3.1. oko polovine ključeva ostaje na starom čvoru 3.2. oko polovine ključeva ide u novi čvor desno od postojećeg 3.3. srednji ključ se “penje” u roditeljski čvor, uz pomeranje ključeva i

pokazivača (rekurzivno korak 3)

26

Page 29: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

4. Ako se “pocjepa” korjeni čvor, srednji ključ ide u novi koreni čvor; visina stabla se povećava za 1

Ako je ključ nađen – unošenje se ne vrši (slučaj bez duplikata)

Brisanje

Brisanje se uvijek svodi na brisanje iz lista 1. Ako se briše ključ iz lista onda

1.1. Ako ostaje dovoljno ključeva, vrši se samo pomjeranje 1.2. Ako ne ostaje dovoljno ključeva onda

1.2.1. Ako susedni brat (čvor) ima “višak” ključeva, najmanji ključ iz desnog (odnosno najveći iz lijevog brata) se “penje” u čvor-prethodnik, a ključ iz prethodnika se “spušta” u čvor iz kojeg smo izbrisali ključ

1.2.2. Ako nijedan susedni brat nema “višak” ključeva, čvor iz kojeg smo izbrisali ključ spaja se sa levim ili desnim bratom, uz dodavanje “razdvojnog” ključa iz čvora-prethodnika. Ako čvor-prethodnik nema dovoljno ključeva, vrši se rotacija preko njegovog čvora-prethodnika, ili spajanje sa bratom

2. Ako se briše ključ iz unutrašnjeg čvora, onda se umjesto njega “penje” najmanji ključ iz njegovog sledbenika; ključ koji se penje briše se iz čvora u kome je bio – pravilo se primjenjuje rekurzivno i svodi na brisanje iz lista

4.2. Problemi sa brzinom pristupa podacima

Upravljanje performansama je osnovni cilj administratora beze podataka. Upravljanje performansama baze podataka nije aktivnost koja se može uraditi jednom za stalno, već je u pitanju proaktivan, kontinuiran i iterativan proces koji traje koliko i eksplatacija baze podataka. Upravljanje performansama MySQL baze podataka podrazumjeva mnogo kompromisa. Pronalaženje najboljih kompromisa bio je prioritetni cilj autora.

Praćenje i optimizacija performansi je osnovni zadatak svakog administratora baze podataka. Skoro svako ko je došao u kontakt sa računarima iskusio je neke probleme sa performansama. Upravljanje performansama može se definisati i kao optimizacija resursa da bi se povećale propusne moći i smanjila konkurencija, istovremeno omogučavajući obradu najvećeg mogućeg opterećenja. Upravljanje performansama je iterativan proces, jer se nakon primjene parametara ponovo prati rad sistema, analizira ostvarena promjena u odnosu na prethodno stanje i ponovo podešavaju parametri.

4.2.1. Faktori koji utiču na performanse

Na performanse baze podataka utiče više faktora:

Mogućnost optimizacije – Mnogi faktori treba da budu optimizovani (kao što su formulacija SQL upita i parametri tabela i servera baze podataka), da bi optimizator baze podataka kreirao najoptimalnije putanje do podataka.

Radno opterećenje – Radno opterećenje je kombinacija trenutnih transakcija, batch poslova i ad hoc upita. Radno opterećenje može drastično da fluktuira iz dana u dan, iz časa u čas, pa čak iz minuta u minut. Ponekad je opterećenje predvidljivo (kao što su velike obrade zarada, prihoda, rashoda i obaveza na kraju meseca ili vrlo slab pristup bazi podataka posle 19 sati, kada je većina korisnika otišla kućama), a ponekad vrlo nepredvidljivo (kao što su ransakcione obrade na zahtev i ad hoc upiti spoljnih korisnika).

27

Page 30: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

Propusna moć – Propusna moć definiše sveukupnu mogućnost računara da obradi podatke. Ona zavisi od brzine U/I operacija, brzine procesora, mogućnosti paralelne obrade i efikasnosti operativnog sistema i ostalog sistemskog softvera.

Konkurencija – Kada su zahtevi za određeni resurs veliki, može doći do konkurencije u pristupu. Konkurencija je stanje u kome dve ili više komponenti koje čine opterećenje sistema pokušavaju da pristupe jednom resursu. Kako konkurencija raste, tako propusna moć opada.

Dinamičko radno okruženje karakteriše brzo povećanje baze podataka, stalni porast broja korisnika i povećavanje složenosti i broja instaliranih aplikacija

4.2.2. Optimizacija MySQL servera

MySQL je poznat kao najčešće korišteni besplatni sistem za bazu podataka, kada je riječ o web aplikacijama. Međutim, on pokazuje slabe performanse koji stvaraju probleme za korisnike servera. U većini slučajeva MySQL nije dovoljno sposoban, tačnije šema baze ili SQL naredbe izazivaju loše ponašanje MySQL-a. Postoje četiri vrste problema koje mogu smanjiti performanse MySQL-a:

Neučinkovit dizajn šeme Loše indeksiranje ili nema indeksiranja Loše napisane SQL naredbe Serverske varijable nisu pravilno podešene

Neučinkovit dizajn šeme

Loš dizajn šeme mnogo smanjuje performanse baze. Dizajn šeme prezentuje strukturu baze podataka. Prije izrade aplikacije, potrebno je sagledati plan baze i ispraviti greške ukoliko postoje. Prilikom dizajniranja baze, podaci se grupišu u različite tabele. Postavljanje svih podataka u istu tabelu, usporit će bazu zbog toga što se neki podaci mijenjaju često, dok neki ostaju stalni.

Loše indeksiranje ili nema indeksiranja

Indeksi pomažu u poboljšanju performansi baze podataka. Indeksiranje je tip tabele koji sadržava primarni ključ i pokazivač na svaki zapis unutar tabele. Loše indeksiranje može utjecati na rad baze podataka. Prilikom indeksiranja, MySQL ne može koristiti indekse ukoliko je u SQL upitu naveden različit redoslijed kolona u odnosu na indekse, tj. redoslijed kolona se gleda sa lijeva na desno i ako je redoslijed različit ili nedostaje kolona u upitu u odnosu na ono što je postavljeno u indeksu, MySQL neće koristiti indeks. Prilikom indeksiranja, potrebno je pazati na duple indekse, oni mogu usporiti ukupan rad. Također ne treba postaviti mnogo indeksa jer oni mogu rad sa bazom da učine mnogo kompleksnijim.

Loše napisane SQL naredbe

Loše pisanje SQL koda može biti opasno za bazu podataka. On također može utjecati na performanse i izazvati ozbiljne sigurnosne probleme baze podataka. Greške SQL koda znači i greška ukupne baze podataka. Postoji nekoliko pravila za pisanje SQL koda:

Koristiti varijable umjesto konstanti u uslovima SQL naredbi Na početku koda postaviti “use strict” Dodati ‘or’ ‘die’ ’$!’ nakon poziva sistema

28

Page 31: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

Serverske varijable nisu pravilno podešene

Da bi dobili maksimalne performanse od baze podataka, potrebno je pravilno podesiti varijable. Postoje mnoge varijable, ali u narednom tekstu biće opisane samo nekoliko njih:

Key_buffer_size: je važna varijabla za tweak. Ako je ova varijabla veća od MyISAM indeski će se čuvati u memoriju. Obično se vrijednost key_buffer_size postavlja na 25%-50% dostupne memorije. Moguće je postaviti bilo koju vrijednost ali više i ne znači bolje, jer može izazvati gubitak memorije.

Setting up query cache: u my.cnf ili my.ini moguće je postaviti zadanu veličinu keš memorije za SQL upite. Prvo odaberemo query_cache_type i nakon toga promijenimo query_cache_size. Postavimo vrijednost tipa na 1 (koji će uključiti keš memoriju) i veličinu na 30M (0 znači da je isključeno). Keš memorija može značajno ubrzati rad aplikacije. Važna stvar je da ne postavimo previše keš memorije za SQL upite jer ovo može usporiti rad ostalih aplikacija poput Apache, php, ruby i sl.

tmp_table_size – ovaj parametar je bitan za velike “group by” i joinove koji koriste temporary tabele. Obratiti pažnju da created_tmp_disk_tables raste ne samo ako je tmp_table_size premali već i ako se koriste blob/text kolone ili ako je ukupna veličina sloga veća od 512 bajtova, u tom slučaju MySQL koristi temporary tabele na disku bez obzira na tmp_table_size; Ako je to slučaj a imate dovoljno RAM-a, setovanje tmp file systema kao tmpfs (na ram disku) će znatno ubrzati ovakve upite

short_buffer: ova varijabla je korisna da poveća brzinu MyISAMCHK operacija. short_buffer koristi se za operacije order by (sortiranje) i group by (grupisanje). Ukoliko server ima 64MB rama može se postaviti short_buffer na 4MB ali je potrebno izračunati i veličinu ostalih buffer-a (record_buffer, key_buffer, join_buffer). Treba voditi računa da veličina postavljene memorije za sve buffer-e ne prijeđe ukupnu količinu rama na server, jer u tom slučaju će operativni sitem početi sa zamjenom memorije iz rama i memorije iz čvrstog diska što može uzrokovati slabim performansama baze podataka. U početku je postavljeno na 2M, ali je moguće povećati memoriju za brži rad baze podataka.

4.2.3. Optimizacija SQL upita

MySQL omogućava da analiziramo upit da bismo saznali za koje se vreme izvrši i kako se tačno izvršava nad sadržajem baze podataka. Najbolje je da se upit izvrši više puta i da zatim izračunamo prosječno vreme njegovog trajanja. Budući da trajanje jednog izvršavanja upita zavisi od ukupnog opterećenja sistema, rezultati samo jednog mjerenja ne mogu se uzeti kao validni. Identifikovanje sporog upita vrši se posmatranjem izvršavanja upita, mjerenjem performansi upita i uvidom u dnevnik sporih upita i dnevnik promjena.

U MySQL-u možemo mjeriti brzinu izračunavanja vrijednosti bilo kog izraza, pa i cijelog upita, pomoću ugrađene funkcije Benchmark().

Pomoću dnevnika sporih upita možemo utvrditi koji se upiti presporo izvršavaju. Obilježavanje sporih upita u dnevnik možemo uključiti pomoću opcije Log_show_queries=ime_datoteke koja je sastavni dio datoteke opcija. Ako uključimo i opciju Log_Long_Format, biće evidentirani i svi upiti pri čijem se izvršavanju ne koristi nijedan indeks. To nam ukazuje čemu treba da posvetimo najviše pažnje pri optimizaciji.

Zadavanjem vrijednosti promjenjivoj Long_query_time određujemo šta je za nas spor upit. Vrijednost se zadaje u konfiguracionoj datoteci ili pomoću komande Set. Vrijednost te promjenjive izražava se u sekundama.

29

Page 32: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

Dnevnik sporih upita možemo čitati neposredno jer je to obična tekstualna datoteka. Jedno od tekućih ograničenja MySQL-a jeste to da ne bilježi spore upite čije izvršavanje traje manje od sekunde.

Na sistemima koji obrađuju relativno veliki broj jednostavnih upita, jedna sekunda traje veoma dugo. Autori smatraju da je u takvoj situaciji poželjno znati kojim upitima je potrebno više od desetinke ili nekog drugog dijela sekunde. To je posebno bitno kada se obrađuju tabele koje sadrže naloge proizvodnje, transporta ili prodaje. Tada se generiše više upita za svaku ranije spomenutu tabelu. Da bi pratili i takve upite, autori predlažu promjenu MySQL izvornog koda i obilježavanje upita u dnevnik sporih upita čije izvršavanje traje više od desetinke sekunde.

MySQL posjeduje ugrađeni mehanizam optimizovanja upita. Pomoću komande Explain možemo saznati kako MySQL tačno izvršava upit da bismo zatim pokušali da ga optimizujemo. Komanda Explain nalaže MySQL-u da objasni kako namerava da izvrši upit. Na osnovu procenjenog broja redova (koji prikazuje komanda Explain), MySQL utvrđuje koji bi bio najbolji redosled spajanja tabela. Ako smatramo da je njegova procena pogrešna, odredbom Straight Join izričito zadajemo redoslijed spajanja tabela. Mjerenjem performansi upita prije i poslije te izmjene, utvrdićemo da li time aplikaciju poboljšavamo ili pogoršavamo.

Uzrok broj jedan loših performansi jeste upotreba tabela kojima nije pridružen nijedan indeks ili nema indeksa za kolone koje pretražujemo. S druge strane, potrebno je veliko vreme da bi se ažurirao veliki broj indeksa svaki put kada se u tabelu upiše novi red ili ažurira postojeći. Kada učitavamo podatke, indeksi su veoma korisni. Kada upisujemo nove redove, odnosno ažuriramo neki podatak ili brišemo postojeće redove, indeksi se ažuriraju što produžava obradu i povećava opterećenje sistema.

Kada bira indeks, MySQL traži odgovarajući indeks koji obuhvata manje od 10% redova tabele. Ako ne uspe da pronaće indeks koji ispunjava te uslove, sekvencijalno pretražuje tabelu. S obzirom da se u projektovanom informacionom sistemu koriste tabele koje imaju po nekoliko stotina hiljada redova, predodređeno sekvencijalno pretraživanje nije prihvatljivo sa aspekta performansi. Autori su vršili testiranje performansi kada se koristi indeks koji obuhvata i više procenata redova tabele. Pokazalo se da je za tabele koje sadrže preko 700 hiljada redova bolje koristiti indeks koji obuhvata i do 15% redova tabele. Takođe, pokazalo se da je za tabele koje sadrže oko 400 hiljada redova povoljnije korištenje indeksa koji obuhvata 12% redova tabele. Autorima je jasno da stvaranje takvih indeksa troši procesorsko vreme ali su takvi indeksi posebno korisni u upitima koji ne mjenjaju stanje tabela. Ako se potpuni rezultat upita može dobiti iz podataka sadržanih u indeksima, iz tabela se neće učitati nijedan red.

Tokom upotrebe baze podataka, u datotekama u kojima se čuvaju podaci raste broj praznina između blokova podataka na mjestima gde su ranije bili izbrisani zapisi ili odakle su zapisi premešteni zato što su nakon ažuriranja postali veći. Te praznine su uzrok slabije efikasnosti.

Trebalo bi da povremeno upotrebimo komandu: Optimize table ime_tabele; koja je MySQL-ov ekvivalent komande za defragmentaciju čvrstog diska. Tako ćemo preurediti podatke u datotekama, ponovo sortirati indekse i ažurirati statističke podatke o tabeli.

30

Page 33: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

5. Implementacija indeksa na bazu podataka – rant-a-car

5.1. Uticaj indeksa na performanse

Za ispisivanje podataka o rezervacijama koje je korisnik ranije obavio možemo koristiti slijedeći SQL upit:

select vozilo.marka, vozilo.tip, rezervacija.kreiranje, privatno_lice.ime, privatno_lice.prezimefrom vozilo, rezervacija, privatno_licewhere rezervacija.vozilo_id=vozilo.idand rezervacija.privatno_lice_id=privatno_lice.idand privatno_lice.ime='Almin'group by privatno_lice.ime, privatno_lice.prezime

Prethodnim SQL upitom dobijamo marku i tip vozila, datum kada je rezervacija kreirana, ime i prezime za sve korisnike kojima je ime Almin. Ukoliko želimo pretraživati i po imenu i po prezimenu potrebno je dodati „and privatno_lice.prezime='Karic'“ da bi dobili rezultate i za ime i za prezime. Problem koji nastaje prilikom ovog upita je veliko vrijeme potrebno da se ovaj upit odradi (slika 6.).

Slika 6. Vrijeme potrebno za izvršavanje SQL upita bez indeksa

Na slici 6. se nalazi vrijeme potrebno za izvršavanje ovih SQL upita. Za različita imena dobijamo različito vrijeme i različit broj redova. Ovo vrijeme od preko 140 sekundi može rezultovati prestankom rada aplikacije koja koristi ovu bazu o trajanju od nekoliko minuta (u ovom slučaju 2,5 minute) tako da to predstavlja ogroman problem ukoliko je u pitanju baza sa velikim brojem podataka.

31

Page 34: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

Za rješavanje ovog problema potrebno je da dodamo indekse na odgovarajuće kolone. S obzirom da se pretraga vrši na osnovu imena ili prezimena privatnog lica i tabela privatno_lice sadrži veliki broj podataka dodaćemo indekse na ove kolone. To možemo uraditi sa slijedećom naredbom:

create index privatno_lice_ime_idxon privatno_lice (ime);create index privatno_lice_prezime_idxon privatno_lice (prezime);

Na ovaj način kreiramo dva nova indeksa u tabeli privatno_lice na kolonama ime i prezime. Osim imena i prezimena, koristimo podatke iz tabele vozilo, marka i tip koje će omogućiti bržu pretragu ovih podataka. Potrebno je dodati i na njih indekse. To možemo uraditi na slijedeći način:

create index vozilo_marka_idxon vozilo (marka);create index vozilo_tip_idxon vozilo (tip);

Ovom naredbom dodajemo dva nova indeksa u tabeli vozilo na kolone marka i tip. Još jedan podatak koji koristimo u SQL upitu je datum kreiranja rezervacije. S obzirom da se u tabeli rezervacija nalazi veliki broj podataka, i na ovu kolonu ćemo dodati indeks:

create index rezervacija_kreiranje_idxon rezervacija (kreiranje);

Ovom naredbom dodajemo novi indeks u tabelu rezervacija na kolonu kreiranje. Rezultat koji dobijemo nakon dodavanja indeksa je prikazan na slici 7.

Slika 7. Vrijeme potrebno za izvršavanje upita nakon dodavanja indeksa

32

Page 35: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

Ukoliko želimo da pogledamo kada je odgovarajuća firma rezervisala određeno teretno vozilo možemo to uraditi pomoću slijedećeg SQL upita:

select vozilo.marka, vozilo.tip, cjenovnik.cijena_radni_dan, rezervacija.podizanje, rezervacija.vracanje, rezervacija.broj_dana, pravno_lice.nazivfrom vozilo, cjenovnik, rezervacija, pravno_licewhere rezervacija.vozilo_id=vozilo.idand rezervacija.cjenovnik_id=cjenovnik.idand rezervacija.pravno_lice_id=pravno_lice.idand pravno_lice.naziv='Magic Plus' and vozilo.marka='FAP'

Ovim SQL upitom dobijamo kao rezultat kada je firma „Magic Plus“ podigla i vratila vozilo marke „FAP“, cijenu za radni dan i broj dana.

Problem kod ovog upita je veliko vrijeme potrebno da se izvrši zbog velike količine podataka. Na slici 8. se nalazi vrijeme potrebno za izvršavanje ovog SQL upita.

Slika 8. Vrijeme potrebno za izvršavanje SQL upita bez indeksa

Sa slike 8. možemo vidjeti da je potrebno vrijeme za izvršavanje ovog upita preko 12 sekundi što predstavlja veliki problem za aplikaciju koja koristi ovu bazu podataka. Ukoliko se postavi više ovakvih upita, aplikacija može prestati raditi na nekoliko minuta (ili čak sati) tako da je i ovo vrijeme ozbiljan problem.

33

Page 36: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

Za rješavanje ovog problem potrebno je da dodamo indekse na odgovarajuće kolone. Pretraživanje se vrši na osnovu naziva pravnog lica. Indeks dodajemo na slijedeći način:

create index pravno_lice_naziv_idxon pravno_lice (naziv);

Na ovaj način dodajemo indeks u tabelu pravno_lice na kolonu naziv koji će omogućiti bržu pretragu naziva pravnog lica. Osim pretraživanja po nazivu pravnog lica, pretraživanje se također vrši po marki vozila (ili tipu). Zbog toga indekse dodajemo na ove kolone na slijedeći način:

create index vozilo_marka_idxon vozilo (marka);create index vozilo_tip_idxon vozilo (tip);

Na ovaj način dodajemo novi indeks u tabelu vozilo na kolonu marka i tip. Osim ova tri nova indeksa, potrebno je dodati još jedan na kolonu podizanje u tabeli rezervacija koji će omogućiti bržu pretragu datuma podizanja vozila:

create index rezervacija_podizanje_idxon rezervacija (podizanje);

Nakon dodavanja indeksa dobijamo rezultat koji je prikazan na slici 9.

Slika 9. Vrijeme potrebno za izvršavanje upita nakon dodavanja indeksa

34

Page 37: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

Ukoliko želimo da pogledamo spisak svih vozila koja su trenutno iznajmljena, možemo koristiti slijedeći SQL upit:

select vozilo.marka, vozilo.tip, agencija.grad, agencija.ulica, rezervacija.podizanje, rezervacija.vracanje, privatno_lice.ime, privatno_lice.prezimefrom vozilo, agencija, rezervacija, privatno_licewhere rezervacija.vozilo_id=vozilo.idand rezervacija.privatno_lice_id=privatno_lice.idand vozilo.agencija_id=agencija.idand vozilo.marka='Audi'and agencija.grad='Tuzla'and rezervacija.podizanje<='2012-03-18'and rezervacija.vracanje>='2012-03-18'

Kao rezultat ovog SQL upita dobijamo listu korisnika koji su iznamjili vozilo marke Audi za dan 2012-03-18. Za obavljanje ovog upita potrebno je vrijeme oko 3,7 sekundi (slika 10.). Ukoliko aplikacija pošalje nekoliko ovakvih upita, tada nastaje problem i dolazi do prestanka rada te aplikacije.

Slika 10. Vrijeme potrebno za izvršavanje SQL upita bez indeksa

Sa slike 10. možemo vidjet da se za četiri upita (koji se razlikuju po imenu grada ili marki vozila) potrebno vrijeme da se izvriši jedan upit oko 3,7 sekundi. Ovaj problem se pojavljuje zbog velike količine podataka u tabeli „vozilo“ tako da je potrebno veliko vrijeme da se pretraži vozilo odgovarajuće marke (ili tipa).

35

Page 38: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

Kao i u prethodna dva primjera ovaj problem možemo riješiti dodavanje indeksa na određene kolone. U ovom slučaju pretraga se vrši na osnovu grada agencije. Međutim tabela „agencije“ ne sadrži veliki broj podataka (18 zapisa) tako da ovdje nećemo dodavit indekse. Osim grada agencije, pretraga se vrši i na osnovu marke vozila. Vozilo sadrži veliki broj podataka i indekse ćemo dodati na slijedeći način:

create index vozilo_marka_idxon vozilo (marka);

Na ovaj način dodajemo novi indeks na kolonu marka u tabeli vozilo, koji će omogućiti bržu pretragu marke vozila. Pretraga se također vrši i na osnovu datuma podizanja i datuma vraćanja vozila iz tabele „rezervacija“ i s obzirom da ova tabela sadrži veliki broj zapisa, potrebno je kreirati indekse i na ovim kolonama. Indekse ćemo kreirati na slijedeći način:

create index rezervacija_podizanje_idxon rezervacija (podizanje);

create index rezervacija_vracanje_idxon rezervacija (vracanje);

Na ovaj način smo kreirali indekse na kolonama „podizanje“ i „vracanje“ u tabeli „rezervacija“, koji će omogućiti bržu pretragu ovih datuma.

Nakon dodavanja indeksa,potrebno je manje vrijeme za izvršavanje SQL upita,slika 11

Slika 11. Vrijeme potrebno za izvršavanje upita nakon dodavanja indeksa

36

Page 39: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

5.2. Implementacija indeksa u MySQL

Na osnovu prethodnih primjera možemo vidjeti da indeksi ubrzavaju pretragu baze podataka sa velikom količinom zapisa. Tabele „privatno_lice“, „pravno_lice“ i „rezervacija“ jako veliki broj zapisa (preko 50 000) tako da one i najviše usporavaju rad cijele baze. Zbog toga je potrebno dodati indekse u ovim tabelama

5.2.1. Dodavanje indeksa u tabeli „privatno_lice“

Kao što smo vidjeli u prethodnim tabela „privatno_lice“ sadrži veliki broj zapisa i potrebno je dodati na odgovarajuće indekse na odgovarajuća mjesta. Pretraga privatnog lica se najčešće vrši po imenu i prezimenu tako da tu i dodajemo indekse

create index privatno_lice_ime_idxon privatno_lice (ime);create index privatno_lice_prezime_idxon privatno_lice (prezime);

Osim imena i prezime, često se pretražuje i „username“ jer prilikom svakog logovanja, aplikacija pretražuje username i password cijele tabele. I ovdje ćemo dodati indeks:

create index privatno_lice_username_idxon privatno_lice (username);

Pretraga po ostalim kolonama je rijetka (tj. podaci iz drugih kolona se ispisuju na osnovu pronađenog imena i prezimena) tako da nije potrebno dodavati indekse na ostale kolone.

5.2.2. Dodavanje indeksa u tabeli „radniik“

Tabela „radnik“ također sadrži veliki broj zapisa i potrebno je dodati na odgovarajuće indekse na odgovarajuća mjesta. Pretraga radnika se najčešće vrši po imenu i prezimenu tako da tu i dodajemo indekse

create index radnik _ime_idxon radnik (ime);create index radnik_prezime_idxon radnik (prezime);

Osim imena i prezime, često se pretražuje i „username“ jer prilikom svakog logovanja, aplikacija pretražuje username i password cijele tabele. I ovdje ćemo dodati indeks:

create index radnik_username_idxon radnik (username);

Pretraga po ostalim kolonama je rijetka (tj. podaci iz drugih kolona se ispisuju na osnovu pronađenog imena i prezimena) tako da nije potrebno dodavati indekse na ostale kolone.

5.2.3. Dodavanje indeksa u tabeli „pravno_lice“

Tabela „pravno_lice“ sadrži veliki broj zapisa kao i tabela „privatno_lice“. U ovoj tabeli najčešće se pretraga obavlja na osnovu naziva pravnog lica a nešto rjeđe po gradu i ulici (tj po adresi). Indeks dodajem na naziv pravnog lica

37

Page 40: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

create index pravno_lice_naziv_idxon pravno_lice (naziv);

S obzirom da se grad i ulica pravnog lica ne pretražuju tako česti, indeksi tu nisu potrebni

5.2.4. Dodavanje indeksa u tabeli „vozilo“

Tabela „vozilo“ također sadrži veliki broj zapisa. U SQL upitima za ovu tabelu se najčešće pretražuju marka i tip vozila. Indekse dodajemo na marku i tip vozila.

create index vozilo_marka_idxon vozilo (marka);

create index vozilo_tip_idxon vozilo (tip);

Osim marke i tipa vozila, moguće da će se često pretraživati i godina proizvodnje ali ovaj tip podataka je integer, tako da se on pretražuje mnogo brže u odnosu na VARCHAR (koji je marka i tip)

5.2.5. Dodavanje indeksa u tabeli „rezervacija“

Tabela „rezervacija“ sadrži najviše zapisa u bazi. Zbog toga su u ovoj tabeli potrebni indeksi za bržu pretragu. U prethodnim primjerima smo vidjeli da se najviše pretražuju datum kreiranja rezrvacije, datum podizanja i datum vraćanja vozila. Indekse ćemo dodati na ove kolone.

create index rezervacija_kreiranje_idxon rezervacija (kreiranje);

create index rezervacija_podizanje_idxon rezervacija (podizanje);

create index rezervacija_vracanje_idxon rezervacija (vracanje);

Ostali podaci se ne pretražuju tako često i oni su tipa integer tako da je brža pretra u odnosu na ove podatke.

38

Page 41: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

5.2.6. Skripta za dodavanje indeksa

Skripta za dodavanje svih potrebnih indeksa je:

create index privatno_lice_ime_idxon privatno_lice (ime);

create index privatno_lice_prezime_idxon privatno_lice (prezime);

create index privatno_lice_username_idxon privatno_lice (username);

create index radnik _ime_idxon radnik (ime);

create index radnik_prezime_idxon radnik (prezime);

create index radnik_username_idxon radnik (username);

create index pravno_lice_naziv_idxon pravno_lice (naziv);

create index vozilo_marka_idxon vozilo (marka);

create index vozilo_tip_idxon vozilo (tip);

create index rezervacija_kreiranje_idxon rezervacija (kreiranje);

create index rezervacija_podizanje_idxon rezervacija (podizanje);

create index rezervacija_vracanje_idxon rezervacija (vracanje);

39

Page 42: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

6. Zaključak

U ovom radu smo analizirali uticaj indeksa na bazu podataka koja sadrži veliki broj zapisa. Ukoliko tabele u bazi sadrže preko 50 000 zapisa, tada se dogodi da je za jedan SQL upit potrebno nekoliko minuta da se izvrši. Ukoliko se postavi više ovakvih upita gdje tabela sadrži mnogo zapisa tada se dešava da aplikacija i baza podataka prestanu sa radom u trajanju od nekoliko sati. Ovo predstavlja veliki problem i za programere i za administratore baze podataka.

Ovaj problem se može riješiti uz upotrebu indeksa. Indekse dodajemo u tabele sa najvećom količinom podataka koji se pretražuju. Ukoliko su indeksi postavljeni na pravo mjesto, oni svojom strukturom omogućavaju da se čak i stotine hiljada podataka pretraži za manje od 1 sekunde. Međutim ukoliko se indeksi postave na pogrešno mjesto, tada SQL upit može trajati i duže nego bez indeksa. Treba voditi računa o tome koliko će se često podaci mijenjati ili ubacivati novi, jer indeksi ubrzavaju selekciju podataka dok usporavaju mijenjanje ili ubacivanje novih.

Ukoliko tabele sadrže manje od 10 000 zapisa, tada indeksi nisu potrebni, jer sam DBMS (sistem za upravljanje bazom) dovoljno brzo obavi sve upite koji su postavljeni i ubacivanje indeksa neće imati značajnu razliku u brzini pretraživanja dok može usporiti ubacivanje novih ili mijenjanje.

Ako tabele sadrže oko 20 000 zapisa, tada prvi upit traje dugo, dok ostali slični upiti se obave brzo. To se dešava zbog toga što se nakon prvog upita rezultati smještaju u keš memoriju servera (query_cache_size). Ovo pomaže ukoliko u upitu promijenimo samo parametar koji tražimo (npr. ime), međutim ukoliko je novi SQL upit tada je ponovo potrebno dugo vremena da se obavi. Ako tabele sadrže oko 80 000 zapisa tada je i za isti upit ponovo potrebno dugo vrijeme da se obavi jer se ne može ta količina postaviti u keš memoriju. Keš memoriju (query_cache_size) možemo povećati na serveru, međutim to nije idealno rješenje.

Integer tipovi podataka se mnogo brže pretražuju u odnosu na VARCHAR tipove, tako da često indeksi nisu potrebni na ovaj tip podataka čak i ako postoji veliki broj zapisa u tabelama.

40

Page 43: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

7. Literatura

[1] Baza podataka Oracle 10g PL/SQL programiranje, Skott Urman, Ron Hardmann, Michael McLaughlin

[2] McGraw-Hill/Osborne, 2004Upravljanje performansama MySQL baze podataka, Blagodar Lovčević, Danilo Obradović, Krstan Bošnjak

[3] Head First SQL Your Brain on SQL -- A Learner's Guide[4] McGraw-Hill - Databases, A Beginner's Guide (2009)[5] http://sh.wikipedia.org/wiki/Virtuelna_privatna_mre%C5%BEa [6] http://www.liderpress.hr/Default.aspx?sid=124537&to=Printable.ascx [7] http://compnetworking.about.com/od/vpn/tp/vpnsoftwarefree.htm [8] http://www.link-elearning.com/site/kursevi/lekcija/6041 [9] http://poincare.matf.bg.ac.rs/~gordana//projektovanjeBP/B-stablo.pdf [10] http://isystemadmin.com/common-mysql-performance-problems-how-to-fix-them [11] http://forge.mysql.com/wiki/Top10SQLPerformanceTips [12] http://www.telfor.rs/telfor2006/Radovi/09_SAA_04.pdf [13] http://cis.stvincent.edu/html/tutorials/swd/btree/btree.html

41

Page 44: Rent-a-car, otpimizacija baze podataka korištenjem indeksa u MySQL

Mišljenje mentora o radu: ____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________

Predložena ocjena: ___________________ ( __ )

Ispitivač:_____________________________

Članovi komisije:

1.___________________________________2.___________________________________

Izdvojeno mišljenje:

Datum odbrane: ___. ___. _______.

42