You are on page 1of 43

JU MJEŠOVITA SREDNJA ELEKTROTEHNIČKA ŠKOLA TUZLA

ŠKOLSKA GODINA 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

MENTOR: Selma Krajinović, dipl. ing. elektrotehnike

UČENIK: Almin Karić Razred: IVT1

TUZLA, maj, 2012.god.

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

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

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

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 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.

Prilikom iznajmljivanja vozila u cijenu se uključuje:

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

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-acar 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

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

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) Nosivost Težina praznog vozila Prikolica (da/ne) Nosivost prikolice 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 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) Naziv firme Sjedište, Adresa, ulica Sjedište, Adresa, kućni broj Sjedište, Adresa, grad 6

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

Za agencije evidentirati

Za korisnika privatno lice evidnetirati

Za korisnika pravno lice evidentirati

-

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

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

Slika 2. UML dijagram za radni proces iznajmljivanje vozila

8

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

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

Atributi entiteta
Tabela 1. Objekat kategorija

Naziv atributa ID Kategorija Detalji

Tip podatka Integer VARCHAR (45) VARCHAR (150)

Obavezno polje da da ne

Primarni ključ da ne ne

Opis Primarni ključ Oznaka kategorije Opis kategorije

Tabela 2. Objekat cjenovnik

Naziv atributa ID Kategorija_id Cijena_radni_dan Cijena_vikend Vise_dana

Tip podatka Integer Integer Decimal (10,2) Decmial (10,2) Decimal (10,2)

Obavezno polje da da da da da

Primarni ključ da ne ne ne ne

Max_kilometara Pocetni_datum Krajnji_datum Koeficijent Tip

Integer DATE DATE Decimal (3,2) Pobrojani

ne da ne ne da

ne ne ne ne ne

Opis Primarni ključ Strani ključ Cijene za radni dan Cijena za vikend Cijena iznajmljivanja za više dana Makismalan broj kilometara po danu Datum pocetka važenja cjenovnika Datom do kojeg vazi cjenovnik Koeficijent za obračunavanje Vrijednosti: VIP, članstvo, obični

11

Tabela3. Objekat vozilo

Naziv atributa ID Kategorija_id Putnicka_vozila Teretna_vozila Agencija_id Marka Tip Godina_proizvodnje Reg_oznake Reg_mjesto Reg_drzava Datum_isteka Zadnje_servisiranje Slika1 Slika2 Slika3

Tip podatka Integer Integer Integer Integer Integer VARCHAR (45) VARCHAR (45) Year VARCHAR (10) VARCHAR (45) VARCHAR (45) Date Date VARCHAR(150) VARCHAR(150) VARCHAR(150)

Obavezno polje da da ne ne da da da da da da da da da ne ne ne

Primarni ključ da ne ne ne ne ne ne ne ne ne ne ne ne ne ne ne

Opis Primarni ključ Strani ključ Strani ključ Strani ključ Strani ključ Marka vozila Tip vozila Registarske oznake Mjesto registracije Država registracije Isek registracije Slika vozila Slika vozila Slika vozila

Tabela 4. Objekat putnicka_vozila

Naziv atributa ID sjedista vrata putnici prtljaznik klima

Tip podatka Integer Integer Integer Integer Integer Bool

Obavezno polje da da da da da da

Primarni ključ da ne ne ne ne ne

Opis Primarni ključ Broj sjedišta Broj vrata Broj putnik Kapacitet prtljažnika DA ili NE

Tabela 5. Objekat teretna_vozila

Naziv atributa ID nosivost tezina

Tip podatka Integer Integer integer

Obavezno polje da da da da da

Primarni ključ da ne ne ne ne

prikolica bool Prikolica_nosivost Integer

Opis Primarni ključ Nosivost vozila Težina praznog vozila DA ili NE

12

Tabela 6. Objekat rezervacija

Naziv atributa ID Cjenovnik_id Vozilo_id Privatno_lice_id Pravno_lice_id Kreiranje Podizanje Vracanje Cijena Broj_dana

Tip podatka Integer Integer Integer Integer Integer DATE DATE DATE Decimal (10,2) Integer

Obavezno polje da da da ne ne da da da da da

Primarni ključ da ne ne ne ne ne ne ne ne ne

Opis Primarni ključ Strani ključ Strani ključ Strani ključ Strani ključ Datum kreiranja Datum podizanja vozila Datum vraćanja vozila Ukupna cijena iznamljivanja. Broj dana za iznajmljivanje

Tabela 7. Objekat privatno_lice

Naziv atributa ID Radnik_id Prezime Ime Username Password Zadnja_posjeta Ulica Kucni_broj Grad Postanski_broj Drzava Broj_kartice Tip_kartice email Broj_pasosa Clanstvo

Tip podatka Integer Integer VARCHAR (45) VARCHAR (45) VARCHAR (45) VARCHAR (45) DATETIME VARCHAR (45) VARCHAR (5) VARCHAR (45) Integer VARCHAR (45) VARCHAR (45) VARCHAR (45) VARCHAR (80) VARCHAR (45) Bool

Obavezno polje da da da da da ne ne ne ne ne ne ne ne ne ne da ne

Primarni ključ da ne ne ne ne ne ne ne ne ne ne ne ne ne ne ne ne

Opis Primarni ključ Strani ključ

Unique polje Unique polje Naziv ulice Broj kuće ili stana

DA ili NE

13

Tabela 8. Objekat pravno_lice

Naziv atributa ID Radnik_id Naziv Ulica Kucni_broj Grad Postanski_broj Drzava Broj_telefona Broj_faxa Email Poreski_broj Naziv_banke Broj_racuna Kontakt_osoba Clanstvo

Tip podatka Integer Integer VARCHAR (45) VARCHAR (45) VARCHAR (5) VARCHAR (45) Integer VARCHAR (45) VARCHAR (20) VARCHAR (20) VARCHAR (80) VARCHAR (45) VARCHAR (45) VARCHAR (15) VARCHAR (45) Bool

Obavezno polje da da da da ne da da ne ne ne ne ne ne ne ne ne
Tabela 9. Objekat radnik

Primarni ključ da ne ne ne ne ne ne ne ne ne ne ne ne ne ne ne

Opis Primarni ključ Strani ključ Naziv firme Naziv ulice Broj kuće ili stana

DA ili NE

Naziv atributa ID Agencija_id Ime Prezime Username Password Zadnja_posjeta Ulica Kucni_broj Postanski_broj Drzava email Potpisivanje ugovora Istek_ugovora Plata JMBG Broj_telefona Funkcija

Tip podatka Integer Integer VARCHAR (45) VARCHAR (45) VARCHAR (45) VARCHAR (45) DATETIME VARCHAR (45) VARCHAR (5) Integer VARCHAR (45) VARCHAR (80) DATE DATE Decimal (10,2) VARCHAR (13) VARCHAR (20) Pobrojani

Obavezno polje da da da da da ne ne ne ne ne ne ne da ne da da ne da

Primarni ključ da ne ne ne ne ne ne ne ne ne ne ne ne ne ne ne ne ne

Opis Primarni ključ Strani ključ

Unique polje Unique polje Naziv ulice Broj kuće ili stana

Mjesečna plata

Vrijednosti: direktor, poslovoĎa, radnik

14

Tabela 10. Objekat agencija

Naziv atributa ID Naziv Ulica Kucni_broj Grad Postanski_broj Drzava Broj_telefona Email Kontakt_osoba

Tip podatka Integer VARCHAR (45) VARCHAR (45) VARCHAR (5) VARCHAR (45) Integer VARCHAR (45) VARCHAR (20) VARCHAR (80) VARCHAR (45)

Obavezno polje da ne da ne da da ne ne ne ne

Primarni ključ da ne ne ne ne ne ne ne ne ne

Opis Primarni ključ Naziv agencije Naziv ulice Broj kuće ili stana

3.2.2. Izrada ER dijagrama pomoću alata MySQL Workbench

Slika 4. ER dijagram u MySQL Workbech

15

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;

16

-- ------------------------------------------------------ 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 , 17

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, 18

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 , 19

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 ) 20

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; 21

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. b. c. d. e. er_model.mwb er_dijagram.pdf create_database.sql sql skripte za kreiranje testnih podataka c++ kod za kreiranje skripti

22

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. 23

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 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

Obično se ne koriste indeksi ako:

Function-Based indeksi  function-based indeks je indeks baziran na izrazima.  Indeks izraz se gradi na osnovu kolona tabele, konstanti, SQL funkcija i userdefinisanih funkcija. Indeks se kreira u MySQL na slijedeći način: CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_ime ON 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:

24

 Svi listovi su na najnižem nivou (stablo je balansirano)  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. 2. 3. 4. Neka je stranica N - korjena stranica Pretražujemo stranicu N na ključ Klj Ako je ključ Klj naĎen, pretraživanje uspešno 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šenja Ako ključ nije naĎen, pretraga je završena u listu 1. Ako ima mjesta u listu, unijeti ključu list uz eventualna pomjeranja 2. Ako je list pun, treba ga “pocjepati”: 2.1. oko polovine ključeva ostaje na starom listu 2.2. oko polovine ključeva ide na novi list desno od postojećeg 2.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 25

3.3. srednji ključ se “penje” u roditeljski čvor, uz pomeranje ključeva i pokazivača (rekurzivno korak 3) 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 26

kućama), a ponekad vrlo nepredvidljivo (kao što su ransakcione obrade na zahtev i ad hoc upiti spoljnih korisnika).  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

27

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. 28

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.

29

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.prezime from vozilo, rezervacija, privatno_lice where rezervacija.vozilo_id=vozilo.id and rezervacija.privatno_lice_id=privatno_lice.id and 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.

30

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_idx on privatno_lice (ime); create index privatno_lice_prezime_idx on 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_idx on vozilo (marka); create index vozilo_tip_idx on 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_idx on 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

31

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.naziv from vozilo, cjenovnik, rezervacija, pravno_lice where rezervacija.vozilo_id=vozilo.id and rezervacija.cjenovnik_id=cjenovnik.id and rezervacija.pravno_lice_id=pravno_lice.id and 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.

32

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_idx on 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_idx on vozilo (marka); create index vozilo_tip_idx on 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_idx on rezervacija (podizanje); Nakon dodavanja indeksa dobijamo rezultat koji je prikazan na slici 9.

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

33

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.vracanje, privatno_lice.ime, privatno_lice.prezime from vozilo, agencija, rezervacija, privatno_lice where rezervacija.vozilo_id=vozilo.id and rezervacija.privatno_lice_id=privatno_lice.id and vozilo.agencija_id=agencija.id and vozilo.marka='Audi' and agencija.grad='Tuzla' and rezervacija.podizanje<='2012-03-18' and rezervacija.vracanje>='2012-03-18' rezervacija.podizanje,

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).

34

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_idx on 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_idx on rezervacija (podizanje); create index rezervacija_vracanje_idx on 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

35

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_idx on privatno_lice (ime); create index privatno_lice_prezime_idx on 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_idx on 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_idx on radnik (ime); create index radnik_prezime_idx on 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_idx on 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

36

create index pravno_lice_naziv_idx on 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_idx on vozilo (marka); create index vozilo_tip_idx on 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_idx on rezervacija (kreiranje); create index rezervacija_podizanje_idx on rezervacija (podizanje); create index rezervacija_vracanje_idx on 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.

37

5.2.6. Skripta za dodavanje indeksa
Skripta za dodavanje svih potrebnih indeksa je: create index privatno_lice_ime_idx on privatno_lice (ime); create index privatno_lice_prezime_idx on privatno_lice (prezime); create index privatno_lice_username_idx on privatno_lice (username); create index radnik _ime_idx on radnik (ime); create index radnik_prezime_idx on radnik (prezime); create index radnik_username_idx on radnik (username); create index pravno_lice_naziv_idx on pravno_lice (naziv); create index vozilo_marka_idx on vozilo (marka); create index vozilo_tip_idx on vozilo (tip); create index rezervacija_kreiranje_idx on rezervacija (kreiranje); create index rezervacija_podizanje_idx on rezervacija (podizanje); create index rezervacija_vracanje_idx on rezervacija (vracanje);

38

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.

39

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

40

Mišljenje mentora o radu: ___________________________________________________________________________ ___________________________________________________________________________ ___________________________________________________________________________ ___________________________________________________________________________ ___________________________________________________________________________ ___________________________________________________________________________ ___________________________________________________________________________ ___________________________________________________________________________ ___________________________________________________________________________ ___________________________________________________________________________ ___________________________________________________________________________ ___________________________________________________________________________

Predložena ocjena: ___________________ ( __ ) Ispitivač:_____________________________ Članovi komisije: 1.___________________________________ 2.___________________________________

Izdvojeno mišljenje:

Datum odbrane: ___. ___. _______.

41