SITNA CREVCA<>
072017<><>

Kako postati programer (10): relacione baze, prosleđivanje parametara funkciji, stack, heap, regex

I programeri imaju štek

U prethodnom broju ste videli kako se prave tabele i kako se obavljaju osnovni upiti u bazu podataka, a sada ćemo pokazati šta je to „relaciono” u relacionim bazama

I dalje ćete koristiti MySQL lokalnu konekciju (server je vaš kompjuter) kojoj pristupate preko MySQL WorkBench grafičkog okruženja. Tekst može da se primeni i na druge relacione baze i SQL jezik. Nastavljamo dalje sa dve kreirane tabele u bazi za evidenciju narudžbina u restoranu, od kojih jedna sadrži spisak gostiju, a druga sadržaj jelovnika. Tabele ste već popunili nekim konkretnim gostima i jelima, a da biste mogli da pratite naš primer pogledajte slike.

 
Vreme je da napravite treću tabelu koja će se zvati „Narudžbine”, i ona će biti karakteristična zato što će sadržati neke informacije iz prethodne dve tabele: gosta koji je izvršio narudžbinu i jelo koje je naručio. Ukoliko je jedan gost imao više od jedne narudžbine, onda će se on naći više puta u ovoj tabeli.

Loš način popunjavanja nove tabele je upisivanje imena gostiju i naziva jela kako narudžbine stižu u restoran. Zamislite da je neki gost za života naručio hiljadu obroka, a onda zamislite da je promenio svoje ime. Pretpostavimo da zbog toga želite da ažurirate njegovo ime u bazi. Onda morate da promenite njegovo ime i u tabeli gostiju i u tabeli narudžbina . Za tabelu „Gosti” to će biti lako, jer je u pitanju samo jedna vrednost, ali za tabelu „Narudžbine” ćete morati mukotrpno da ispravljate hiljadu unosa, ili da pišete posebnu SQL skriptu koja bi to obavila. Poseban problem je ako postoji više gostiju sa istim imenom, jer na ovaj način ne možete da ih (lako) razlikujete.

Foreign key

 
Pravi način popunjavanja treće tabele jeste da se u njenim kolonama nalaze veze (relacije) sa prethodnim tabelama. Kolona gostiju neće sadržati imena gostiju, već njihove identifikacione brojeve iz tabele „Gosti”. Slično tome, kolona jela će sadržati identifikacioni broj jela iz tabele „Jelovnik”. Ove veze se nazivaju spoljnim ključevima (foreign key). Sada se tabela „Narudžbine” sastoji od dve kolone sa ID brojevima, što nam baš i ne govori mnogo na prvi pogled. Međutim, korišćenjem upita moguće je spisak narudžbina prikazati u obliku koji je mnogo čitljiviji.

Join

Sintaksa SQL jezika koja se koristi je sledeća:

SELECT (prikaz svih kolona koje nas zanimaju iz tabela koje nas zanimaju)

FROM (iz koje tabele će se inicijalno vući podaci)

JOIN (tabela za povezivanje sa ovom od malopre) ON (koje kolone između tabela su povezane)

Na ovaj način možete da prikažete podatke iz tabele „Narudžbine”, koja je povezana sa tabelom „Gosti”, tako da prikažete ime gosta. U prevodu, prikazaće se imena svih gostiju koji su nešto naručili. Da ste stavili RIGHT JOIN umesto JOIN, prikazali bi se čak i oni gosti koji nisu imali nikakvu narudžbinu. Potrebno je da naučite sve vrste JOIN kombinacija, sa napomenom da je JOIN isto što i INNER JOIN, a LEFT JOIN i RIGHT JOIN su isto što i LEFT OUTER JOIN ili RIGHT OUTER JOIN.

Ako sada promenite ime gosta u njegovoj tabeli, zahvaljujući relacijama koje smo uspostavili, automatski će se promeniti ime ovog gosta svuda gde se on pominje u tabeli „Narudžbine”. Uz to, baza neće dozvoliti unos u tabelu „Narudžbine” gosta koji ne postoji i zabraniće brisanje gostiju iz baze koji su nešto već naručili, jer bi se tako uzurpirala tabela sa „Narudžbinama”.

One-to-Many, Model, EER Diagram

Foreign keyeve ste mogli da napravite direktno preko opcije alter table i biranjem odgovarajućeg taba. Međutim, postoji lakši način dizajniranja tabela u bazi i relacija između njih. Radi se o modelu baze, a svaki model može da se predstavi EER dijagramom. EER dijagram je odličan za vizuelni prikaz tabela i relacija između njih u vidu nodova povezanih linijama (vidi sliku). Model i dijagram možete napraviti iz postojeće baze opcijom DataBase -> Reverse Engineer u Workbenchu, a možete da ih kreirate i „od nule”. Još jedan bitan termin u vezi sa bazama je kardinalnost relacije, što se lako može videti putem dijagrama.

 
Kliknite dva puta na relaciju između dve tabele i pored foreign keya videćete da je kardinalnost relacije one-to-many. To znači da jedan gost iz tabele „Gosti” može da se pojavi više puta u tabeli „Narudžbine”. Sa druge strane, nije dozvoljeno da jedna narudžbina bude vezana za dvoje ili više gostiju. Ukoliko ste odlučili da tabele dizajnirate preko dijagrama, prilikom pravljenja one-to-many relacije prvo kliknite na tabelu na koju će se odnositi „many” deo relacije, u ovom slučaju na tabelu „Narudžbine”.

Ako biste izmenili relaciju da bude one-to-one, onda bi svaki gost mogao da ima samo jednu narudžbinu. Ukoliko bi isti gost poručio novo jelo, baza bi prijavila grešku da unos gosta u tabelu „Narudžbine” nije jedinstven.

Vrlo važna napomena je da menjanjem modela ne menjate automatski svoju bazu. Model je odvojen od baze i potrebno je da ga nakon svake izmene sinhronizujete – u ovom slučaju sa vašom lokalnom bazom, ali možete i sa bilo kojom drugom kojoj imate pristup. Model je zapisan u fajlu na hard disku, pa ga možete koristiti da, na primer, sinhronizujete bazu svog programa koja se nalazi na zvaničnom serveru i njenu lokalnu kopiju na vašem računaru.

Ako ste napravili izmenu da konekcija između gostiju i narudžbina bude „1-1”, nakon sinhronizacije sa bazom videćete da se vaša baza promenila. Naime, kolona gosti u tabeli „Narudžbine” dobila je atribut „UQ” (unique). Naravno, ovo ste mogli i ručno da uradite i bez posezanja za modelom/dijagramom.

Baze – zaključak

Ovo su neke osnove relacionih baza podataka. Posebna problematika je da sa bazom povežete aplikaciju koju programirate. Tada je čest korak da napravite klase sa poljima koja su slična tabelama i kolonama iz baze, a takve klase se obično nazivaju entitetima. Zatim, nije loše znati za pojam transakcije u bazi. To je mehanizam bezbednosti u slučaju nepredviđenog prekida unosa serije (bloka) podataka u bazu. Podaci iz serijskog unosa nisu vidljivi prilikom upita sve dok se ne završi i poslednji unos. Takođe, baza ima mogućnost da vrati (roll-back) podatke na prethodno ispravno stanje, ukoliko je došlo do nepredviđenog prekida upisa. Ukupno postoje četiri osnovna sistema zaštite koji se skraćeno nazivaju ACID. Za kraj, napominjemo da model i EER dijagram služe samo za dizajniranje baze, ne i za unos podataka u nju.

Za razliku od relacionih, postoje i nerelacione baze podataka. One imaju malo drugačiju filozofiju, i jedna od najočiglednijih razlika je da njihove tabele nemaju striktnu strukturu. Na primer, tabela u jednom redu može da ima dva polja, u sledećem deset, ili, drugim rečima, različit broj kolona. Svako polje može da sadrži drugi tip podataka.

Pass by reference/value

 
Do sada nismo istakli jednu vrlo važnu stvar u programiranju, a to je – šta se dešava sa promenljivama kada ih prosledite nekoj funkciji. Odgovor opet zavisi od programskog jezika u kom radite, ali princip ćemo videti u Javi. Pre svega potrebno je da podsetimo da postoje primitivni tipovi promenljivih kao što su int ili boolean, a zatim i referentni tipovi kao što su promenljive neke klase. Promenljive neke klase smo do sada nazivali objektima, ali od sada ćemo ih zvati referencama, kako bismo lakše vodili ovaj odeljak. Objekat je zapravo primerak klase u memoriji sa popunjenim vrednostima na koju pokazuje referentna promenljiva.

int x = 5;

int y = x;

y = 8;

System.out.println(x); //5

System.out.println(y); //8

NekaKlasa k1 = new NekaKlasa();

NekaKlasa k2 = new NekaKlasa();

k1.y = 5;

k2 = k1;

k2.y = 7;

System.out.println(k1.y); //7

System.out.println(k2.y); //7

Zašto je promenjena vrednost promenljive k1? Poenta je u tome što su to referentne promenljive. Kada ste napisali korak k2 = k1, vi ste podesili da k2 pokazuje (referiše) na deo memorije (objekat) na koji pokazuje i k1. Sada, bilo da menjate k1 ili k2, menjate isti objekat.

Možete se zapitati kako onda da kopirate referentne promenljive tako da pokazuju na objekte iste klase, a da se menjanjem jedne ne menja i objekat druge. Potrebno je upravo to, da pokazuju na dva različita objekta istog tipa. To se radi ručnim kopiranjem objekata (zbog jednostavnosti pretpostavimo da je polje y primitivna promenljiva.):

NekaKlasa k1 = new NekaKlasa();

NekaKlasa k2 = new NekaKlasa();

//k1 = k2; preskacemo

k1.y = 5;

k2.y = 5;

Ako biste pravilnije pratili OOP princip, napisali biste tzv. copy konstruktor koji vrši isto ovakvo izjednačavanje po poljima, pa biste k2 kreirali sledećom linijom kôda:

NekaKlasa k2 = new NekaKlasa(k1);

Sada stižemo do pitanja šta se dešava kada promenljivu prosledite u funkciju. Za Javu je poznato da radi po principu pass-by-value, tj. da se u funkciji kreira kopija prosleđene promenljive. U slučaju integera, menjanjem promenljive u funkciji nećete uticati na vrednost originalne promenljive. Međutim, u slučaju referenci to ne važi. Referentna promenljiva unutar funkcije je zaista kopija originalne reference, ali i kopija i original i dalje pokazuju na isti objekat.

package XXX;

public class XXX {

static class NekaKlasa {

int y;

}

public static void main(String[] args) {

int x = 5;

NekaKlasa k = new NekaKlasa();

k.y = 10;

System.out.println(x); //5

System.out.println(k.y); //10

promeni(x);

promeni(k);

System.out.println(x); //5

System.out.println(k.y); //20

}

public static void promeni(int x1){

x1 = 6;

}

public static void promeni(NekaKlasa k1){

k1.y = 20;

}

}

Postoje mehanizmi kojima ova pravila mogu da se premoste. U jeziku C++ možete korišćenjem znaka „&” forsirati da prosleđujete promenljivu po referenci. Na taj način možete da menjate originalnu primitivnu promenljivu. U slučaju Jave ne postoji način da se parametar prosledi kao referenca. Ali, pomenuli smo da u Javi postoje objekti analogni primitivnim promenljivama, pa je tako int primitivan, a Integer objekat. Ako ste promenljivu u startu definisali kao Integer (objekat), menjanjem parametra funkcije ipak menjate originalni Integer.

Slično, postoje načini da se reference prilikom prosleđivanja funkcija razdvoje, tako da svaka pokazuje na sopstveni objekat.

Stack, heap, rekurzija

Ukoliko idete na intervju za posao programera, jedno od pitanja koje možete dobiti je šta je to stack ili heap memorija. Ukratko, stack je memorija u koju će sistem „stavljati” sve pozive funkcija sa njihovim lokalnim promenljivama. Moguće je da na steku bude više od jedne funkcije i svakoj se dodeljuje tzv. stack frame. Kako se funkcija završi, tako se ova memorija čisti po LIFO principu, tj. ono što je poslednje ušlo na stek, prvo se iz njega briše. Stek memorija je brža i sistem za nju odvaja manji prostor unutar cele memorije. Sa druge strane postoji heap memorija u kojoj se npr. čuvaju objekti (dok se na steku čuvaju reference ka njima).

Čuveni sajt Stack Overflow dobio je naziv po grešci koju operativni sistem izbacuje kada se prepuni stek memorija. Ovu grešku je vrlo lako reprodukovati pozivom beskonačne rekurzivne funkcije. Rekurzivna funkcija nije ništa drugo nego funkcija koja u svom telu poziva samu sebe. Nećemo pisati primer, jer vrlo lako možete da pronađete implementaciju klasične rekurzivne funkcije pomoću koje se pronalazi faktorijel nekog broja. Kada budete želeli da proširite znanje o rekurziji, pronađite šta je to tail rekurzija, koja ima neke specijalne osobine i kojom se izbegava „Stack Overflow” greška. Svaki put kada program „pukne”, IDE će izlistati stek (stack trace) i među trenutno aktivnim podacima u stek memoriji pokazati u kojoj liniji kôda je došlo do greške. A ukoliko nestane prostora u heap memoriji, prikazuje se greška „Out of Memory Error”.

Regularni izrazi

Za kraj ovog nastavka našeg serijala, nije loše znati da postoji nešto što se zove regex (regular expression). U pitanju je niz oznaka kojim se kreira kriterijum za pronalaženje niza karaktera. Pretpostavimo da želite da pretražite dugačak string ili, recimo, sadržaj nekog fajla. Uz pomoć regularnog izraza možete vrlo precizno da pronađete određene delove teksta kako biste ih, na primer, zamenili nekim drugim tekstom. Kombinovanjem regex uslova mogu se stvoriti neverovatno moćni uslovi pretrage.

Ognjen POPOVIĆ

 
 NOVE TEHNOLOGIJE
Da li smo otkrili vanzemaljske megastrukture?

 TRŽIŠTE
Pružaoci cloud usluga

 NA LICU MESTA
PHP Srbija Conference 2017
Symphony jubilej
HTC U11 promocija
Vip Mobile jubilej
Konferencija „Intelektualna svojina i Internet”
Seminar „Think LEAN” (najava)

 KOMPJUTERI I FILM
Spider-Man: Homecoming
Valerian
Filmovi, ukratko

 SITNA CREVCA
Kako postati programer (10): relacione baze, prosleđivanje parametara funkciji, stack, heap, regex
Šta mislite o ovom tekstu?

 VREMENSKA MAŠINA
NAFTA, redov Rajan i GTA: San Andreas

 PRST NA ČELO
Lekcija iz poštovanja
Home / Novi brojArhiva • Opšte temeInternetTest driveTest runPD kutakCeDetekaWWW vodič • Svet igara
Svet kompjutera Copyright © 1984-2015. Politika a.d. • RedakcijaKontaktSaradnjaOglasiPretplata • Help • English
SKWeb 2.54
Opšte teme
Internet
Test Drive
Test Run
PD kutak
CeDeteka
WWW vodič
Svet igara



Naslovna stranaPrethodni brojeviOpšte informacijeKontaktOglašavanjePomoćInfo in English

Svet kompjutera