PDA

Pogčedajte punu verziju : DB Abstraction Layer, koji koristite ?


ivanhoe
31. 01. 2006., 19:33
i da li uospte koristite neki ? :)

Jako se mnogo prica o portabilnosti koda sa jedne baze na drugu, ali nisam siguran koliko to prakticno ima znacaja? Da li vam se ikada desilo da ste naknadno morali da portujete neki web projekat sa jedne baze na drugu?

AFAIK za vecinu web sajtova se sa 99% sigurnosti moze tvrditi da mysql moze da odradi mnogo vise nego sto ce im ikada trebati, pa mi se sva ta prica o portabilnosti cini vise kao hip, nego kao real world potreba...a i koliko god dobra bila klasa, prelaz sa jedne baze na drugu je uvek mnogo vise gnjavaze od proste promene par parametara....

Koje je vase misljenje o tome da li se isplati koristiti abstraction layere uopste?

ti paket ubrzavaju razvoj, i omogucavaju cistiji kod, sto je svakako plus...ali opet vecina njih (recimo Pear:DB ili AdoDB za PHP) imaju gomilu dodatnog koda koji se izvrsava da bi osigurao da SQL upit bude portabilan medju bazama, a ako cu ja koristiti samo npr. mysql to je cisto trosenje resursa. Takodje upotrebom tih klasa postaje relativno komplikovano izvesti neke specificne cake vezane za konkretnu bazu, a koje bi mogle da ubrzaju stvari (npr. jako zgodna auto inkrement polja u mysql..)

Kakva su vasa iskustva?

Ilija Studen
31. 01. 2006., 20:08
Ja koristim Propel (http://propel.phpdb.org/), a on kao abstraction layer koristio Creole (http://creole.phpdb.org/wiki/wiki.php). Dobra stvar je što zajedno omogućavaju vrhunsku portabilnost jer te ne zanima koja je baza ispod. Definišeš koje objekte želiš, kako su povezani i na osnovu toga se za konkretnu platformu generišu konstrukcija baze, klase, relacije među njima... Konstrukcija je u XML formatu tako da je nezavisna od platforme.

Problemi:

- Generiše se mnogo koda
- Potrebno dosta vremena da se sav taj kod parsira tako da je distribucija u izvornom obliku ludost. U produkciji je najpametnije koristiti enkodirane fajlove jer se tu preskače parsiranje. Takođe, pametnim korišćenjem __autoload() funkcije se isto mogu ostaviriti uštede...
- Ovakav kod jeste sporiji, ali u ekodiranom obliku uštede u performansama su zanemarljive u odnosu na dobijeno vreme u razvoju / portovanju (hardver - jeftin, vreme dobrog programera - skupo). Ko je bar jednom koristio nešto slično zna o čemu pričam. Ostali samo mogu da nagađaju ;)
- Nije za male projekte

Ukolike je projekat bar malo složen (5 tabela +) i nisu potrebne maksimalne performanse (ovde mislim na stvarno ekstremnu posećenost) uvek preporučujem korišćenje abstrakcionih slojeva. Ubrzavaju razvoj, povećavaju portabilnost koda i pomažu ti da umesto da razmišljaš o tabelama u bazi i poljima razmišljaš o objektima, njihovim relacijama i konkretnim problemima koje treba da rešiš.

PS: Do sada nisam bio u situaciji da moram da portujem kod na drugi tip baze. Lakoća portovanja nije osnovni razlog zašto bi se neko odlučio na korišćenje ovakvih biblioteka. Jednostavno olakšavaju i ubrzavaju rad, a portabilnost mu tu dođe kao fin dodatak.

zextra
31. 01. 2006., 20:35
Home made db wrapper mi radi posao. Jos uvek nisam imao realnu potrebu da koristim drugi db engine, osim mysql...

Inace, na phpclasses.org se bukvalno svaki dan pojavi novi mysql wrapper, ponekad i po dva komada :)

dinke
31. 01. 2006., 20:37
Ja u principu do sada nisam koristio nikakav DB abstraction layer, niti sam se susreo sa potrebom da moram da prebacujem kod sa jedne baze na drugu. SQL pisem sam, a koristim jednostavan OOP MySQL API koji sam sam razvio. Ovih dana prelazim i ja na PHP 5 (i to odmah 5.1) pa cu probati PDO ako stignem.

I ja sam od onih koji smatraju da je koriscenje biblioteka tipa PEAR::DB kada to nije apsolutno neophodno uludo trosenje resursa.

Bojan Zivanovic
31. 01. 2006., 21:15
ADOdb (za manje projekte ADOdb Lite)

Ilija Studen
31. 01. 2006., 21:18
Zaboravih da napomenem, a možda iz mog posta nije očigledno.

Mislim da je apstrakcija baze podataka polukorak. Nešto što nema puno smisla... Možda u tolikoj meri da je definisan standardan API i par pomoćnih metoda koji sprečavaju fizikalisanje. Dalje od toga je uludo trošenje resursa.

Međutim apstrakcija kompletnog pristupa podacima ima znatno više smisla po meni. To je kompletan korak, kad ne morate da pišete SQL i razmišljate o bazi. Jedan od slučajeva je da se ispod klasa i ne nalazi baza već možda XML fajl. Sama aplikacija toga nije svesna (i ne bi treba da bude). Njoj je bitno da do podataka dođe, a na koji način će se oni "očuvati" između zahteva treba da prepusti potpuno automatizovanom sloju.

Problem i rešenje fino opisani ovde (http://en.wikipedia.org/wiki/Object-relational_mapping)...

zextra
31. 01. 2006., 21:28
Da, zato se jedno zove wrapper, a drugo abstraction layer, zar ne?

Dušan Dželebdžić
31. 01. 2006., 22:13
Koristim ezSQL wrapper (pokupio ga sa phpclasses), za sitnije sajtove koje sam radio - sasvim ok. Ne verujem da će bilo koji od tih sajtova prelaziti na neke egzotične baze, tako da mi nije bila potrebna nikakva apstrakcija, a i volim direktno da pričam sa bazom :D

Ah da, ima i sjajnu funkciju za debugovanje queryja.

bluesman
31. 01. 2006., 22:42
Da ne bude da kvarim žurku... koliko vas je imalo priliku da menja bazu podataka na nekom projektu pa da mora da ima dobar "abstraction layer", koliko vas je uopšte započelo sa jednom bazom a završilo sa drugom, koliko vas je uopšte radilo bilo šta drugo osim mysql i ponekad pgsql?

A da ne govorimo da obično takve stvari utiču na performanse, naročito na sajtovima sa većim brojem poseta.

Ja imam jednu svoju klasu za rad sa mysql, i samo je dorađujem godinama... klasa je napravljena tako da mi olakšava rad sa smarty, najviše zbog assign, radi u PHP3, 4 i 5, i iskreno nikada mi nije trebalo ništa više od toga.

Još kada čujem da nekome treba "abstraction layer" da se nebi petljao sa maysql i kreiranjem querija, onda stvarno ne shvatam kako neko može da se "bakće" sa web programiranjem, piše profesionalne web aplikacije, optimizuje ne samo php kod nego i mysql querije, a da ne želi da se bakće sa mysql.

zextra
31. 01. 2006., 22:51
Koliko sam ja razumeo, radi se o radu sa objektima umesto sa zivim podacima i sakrivanju istih od programera, sto omogucava apstrakciju na visokom nivou, npr. za potpuno dinamicke aplikacije (CMS frameworks?)...

Kao sto sam vec rekao, nista bolje od rucnog sastavljanja querija i obrade istih u 2-dimensional array :)

Ilija Studen
31. 01. 2006., 23:56
Znao sam da će Blues ovako odreagovati. Već smo jednom vodili ovakvu diskusiju gde sam ja popustio. Ali sada je moj kung-fu zreliji i bolji :D

Još kada čujem da nekome treba "abstraction layer" da se nebi petljao sa maysql i kreiranjem querija, onda stvarno ne shvatam kako neko može da se "bakće" sa web programiranjem, piše profesionalne web aplikacije, optimizuje ne samo php kod nego i mysql querije, a da ne želi da se bakće sa mysql.

Nadam se da će ovo ispasti dobar fazon (to je osnovna namera):

Još kad čujem da nekom treba automobil kako se ne bi petljao sa biciklom i pedalanjem onda stvarno ne mogu da shvatim kako neko može da dođe na ideju da krene iz tačke A u tačku B, prelazi taj put uz optimizaciju uloženog truda, a da se ne bakće direktno sa svojim prevoznim sredstvom.

Naravno, biciklo je sasvim dovoljan za većinu svakodnevnih zadataka, ali mi ipak volimo udobnost koju nam automobil pruža, štiti nas od vremenskih nepogoda i uopšteno ulažemo znatno manje sopstvene energije u rešavanje problema. Automobil više troši i skuplji je... Stvari koje smo spremni da oprostimo jer nam zauzvrat pruža dovoljno da opravda te stvari.

Ako treba na brzaka da odletim do obližnje prodavnice sešću na biciklo, ali ako treba da pređem nešto ozbiljniji put onda ću se definitivno odlučiti za auto. Po meni je ovo sasvim logičan način razmišljanja.

---

Tražeći optimalno rešenje za opis podataka sa kojima aplikacija barata našao sam sledeće gradivne objekte:

- sam objekat (korisnik, grupa, vest...) sa svojim svojstvima
- relacije (blog unos ima više komentara, komentar pripada jednom blog unosu)
- validatori (naslov unosa ne sme biti prazan, email adresa mora odgovarati navedenom formatu)

Ono što tebe ne treba da zanima je na koji način će se opisani objekti čuvati (bitno je da budu sačuvani) i kako će se razrešavati relacije među njima. Ono što treba da te zanima je da ti ti objekti budu dostupni i da budu trajni, te da objekat koji sadrži neisprvne podatke ne smeju biti sačuvani (uloga validatora). Klasična crna kutija: ne zanima te šta je unutra dokle god radi ono što si joj ti naložio da radi.

Ako si precizno definisao svojstva objekata, relacije među njima i pravila ti si odradio nekih 70-90% posla. Sve što treba da uradiš je da programiraš izuzetke od opšteg ponašanja i napraviš korisnički interfejs.

Propel ti recimo omogućava da navedena pravila definišeš pomoću jednostavnog XML fajla. Na osnovu njega dobijaš generisane klase, SQL za generisanje konstrukcije baze (u skladu sa platformom), a u fazi razvoja je i mehanizam da dobiješ i gotove forme. 100% free!

Rails ti sa druge strane pravi definiciju analizirajući tabele u bazi podataka dok specifičnosti koje ne može sam da zaključi (validatori, relacije...) definišeš ti unutar model klase pomoću par krajnje jednostavnih komandi. Zauzvrat ćeš čak dobiti potpuno funkcionalan model plus osnovne forme i listanja. Pogađate? 100% free!

---

Za jednostavne stvari se ne ispati dovoditi artiljeriju, ali ako je problem sa kojim se suočavaš iole ozbiljniji zna se. Uštede u vremenu su ogromne, a to znaju osobe koje su radile sa sličnim rešenjima.

Rails važi za ultra produktivno okruženje. Razlog: konvencije, kvalitetan ORM, testiranje, opšte stvari se razrešavaju automatski, programer definiše samo izuzetke. Mislite o tome...

Pedja
01. 02. 2006., 00:05
U principu za svaki projekat pravim zasebam wrapper koji se u sustini sastoji od namenskih funkcija koje izvrsavaju odredjenje upite ili obrade nad tabelama. Tako SQL kod imam samo na jednom mestu, a parametrima funkcija mogu u nekoj meri da uticem na same SQL komande.

Nikad mi se nije desilo da sam menjao bazu na vec gotovoj aplikaciji. U stvari jeste se desilo ali ne sa web aplikacijom.

Naravno da bih voleo da imam mogucnost da samo definisem tabele i relacije a da mi neki "abstraction layer" sam cupa podatke ali nekako mi je nezamislivo da je to izvodljivo a da bude dovoljno jednostavno da opravda trud da se sve to namesti i koristi. Nekako mi ne ide da neki tamo skript moze da sastavi SQL upit koji radi bas ono sto mi treba, a jos manje mi ide da ocekujem da isti SQL upit radi na vise baza, ako ni zbog ceg drugog, ono zbog sitnih nekompatibilnosti SQL komandi kod razlicitih baza.

Sve u svemu, trudim se da SQL kod odvojim od PHP koda, na slicnom principu kao sto se trudim da odvajam aplikacioni od prezentacionog koda aplikacije, ali se uopste ne zanimam mogucnoscu portovanja na drugu bazu.

Voleo bih da vidim neki konkretan primer kako abstrakcioni layer olaksava posao.

bluesman
01. 02. 2006., 00:08
Znao sam da si zbog mene to i napisao, pa sam ti pricinio zadovoljstvo da oprobas ponovo svoj Kung-fu :)

Igrom slucaja, zbog onih problema ovih dana, bacio sam pogled na recimo www.termomont.co.yu . Proveravao sam sajt online, da li radi i bilo mi je cudno zasto se tako vuce kada je obican html. Mislim, nije obican html, ali moze da bude.

Odmah mi je palo na pamet da je Ilija povukao sav svoj Kung-fu, i opalio iz teskih haubica na ovaj projekat, pa sam morao da zadovoljim znatizelju jer mi je bilo nelogicno da se, tako jedan jednostavan sajt, tako vuce.

Naravno, nisam ni imao nameru da gledam detalje, samo sam pogledao root i video ono sto sam i ocekivao - gomile "layera", raznih "ja ne volim bicikl" klasa, jednostavno kao da si skinuo sacmaru sa zida da ubijes komarca.

Kao što sam ti onomad rekao, imaćeš jako ozbiljan problem kada budeš uradio neki sajt na koji će se kačiti gomila ljudi pa ćeš imati i po 100 query-ja u sekundi. Ako i preživi sajt, vući će se maksimalno....

A sve to zato što sedaš u auto i kada ideš u toalet.

Ilija Studen
01. 02. 2006., 00:08
Naravno da bih voleo da imam mogucnost da samo definisem tabele i relacije a da mi neki "abstraction layer" sam cupa podatke ali nekako mi je nezamislivo da je to izvodljivo a da bude dovoljno jednostavno da opravda trud da se sve to namesti i koristi. Nekako mi ne ide da neki tamo skript moze da sastavi SQL upit koji radi bas ono sto mi treba, a jos manje mi ide da ocekujem da isti SQL upit radi na vise baza, ako ni zbog ceg drugog, ono zbog sitnih nekompatibilnosti SQL komandi kod razlicitih baza.

Lista biblioteka koje rade baš to (http://en.wikipedia.org/wiki/Object-relational_mapping#O.2FRM_frameworks_and_tools) :)

---

www.termomont.co.yu - da ne dužim priču i odlazim u offtopic: sajt je takav kakva je s dobrim razlogom. Speed king nije, ali nije ni spor koliko vidim.

bluesman
01. 02. 2006., 00:11
Samo bih voleo da mi neko pokaže jedan abstraction layer, ili kako god ih već zovete, koji će za jednu dobro normalizovanu bazu da napiše query sa 2-3 join-a.

Znam da će ilija da kaže da se to piše ručno, ali sorry, ako mi treba "abs layer" da ne bih pisao "SELECT * FROM USERS LIMIT 10" onda mi takav Kung-fu ne treba. Znaci, otpada prica o "crnoj kutiji" koja radi savrseno a ti samo sedis i vozis (naravno sa proturenim laktom kroz prozor) :)

ivanhoe
01. 02. 2006., 00:13
da, ja sam i poceo pricu upravo zato sto ja volim da radim direktno sa SQL-om, pa pretvaranje SQL upita u komplikovan poziv metoda nekog objekta kreiranog unapred ne vidim kao neku veliku ustedu vremena, a meni to smanjuje jasnocu koda... pogotovo ako se jos koristi i neki custom wrapper oko toga, onda neki jadnik koji treba da gleda moj kod nema nikakve sanse da brzo shvati o cemu se radi u kodu...

naravno to je sve pitanje navike...

Ilija Studen
01. 02. 2006., 00:34
Samo bih voleo da mi neko pokaže jedan abstraction layer, ili kako god ih već zovete, koji će za jednu dobro normalizovanu bazu da napiše query sa 2-3 join-a.

Kao što već rekoh, sistem radi opšte stvari, izuzeci su na programeru. Statstički gledano, odnost "jednostavnih" operacije tipa:

// Primer čija je jedina svrha da pokaže kako izgledaju zahtevi!
$user = UserPeer::retreiveByPk(12);
$group = $user->getGroup();
if($group instanceof Group) {
$all_users = $group->getUsers();
}

su daleko (sa naglaskom na daleko) brojnije od kompleksnih upita. Propel ima kompletnu podršku za JOINove kroz Criteria klasu, a u generisanim klasama dobijaš metode za brzo izvršavanje JOIN upita nad tableama među kojima su relacije poznate. Do koje kompleksnosti upita možeš da ideš sa Criteria klasom možeš da saznaš ako postaviš pitanje na Propel mailing listi.

Slično je i sa ActiveRecordom (Rails), s tim da je osnovna poenta kod Railsa "less everything" tako da su malo "štedeli" na podršci za stvari koje se koriste u jako retkim situacijama te samo "zagađuju" kod nepotrebnim stvarima.

Ja sam svoje argumente izneo. Kao neko ko je koristio oba metoda (sa i bez slojeva kao što je Propel) kažem da ti slojevi uz uglavnom zanemarljiv pad performansi donose veću produktivnost, sigurnije i robusnije aplikacije koje se lakše održavaju. Ko se ne slaže nek proba da argumentovano dokaže suprotno :D

PS: Blues, verbalni terorizam: cepidlačenje i hvatanje za sitnice ;)

bluesman
01. 02. 2006., 00:49
Moraš da paziš šta govoriš kada pričaš sa mnom :)

Ma nije, nego kada navedeš primere, pa ih još bolduješ, ja baš volim da upotrebim tvoje primere da dokažem svoje.

Pazi, ako ću ja da definišem "kriterijume", koristim 66 klasa i 20-ak include da bih napisao jedan JOIN koji mogu iz glave da sastavim onoliko brzo koliko mi daktilografksa sposobnost dozvoljava, onda ću rađe da propustim te "fensi" stvari.

A što se argumenata tiče, pa ja ti baš malo pre dokazah suprotno. Mada, ne očekujem da ćeš ih prihvatiti, poučen prethodnim iskustvima :)

Evo neka ti pokaže nixa, meni je pokazivao pre neki dan, kako radi frog design. Čuo si za njih? To ti je jedna od jačih globalnih web design firmi. Imaju klijente koji barataju milionima dolara kao klinci "Yu-Gi-Oh!" sličicama (ko ima decu, shvatiće :) )... pa da vidiš kakav kod im proizvode. Ceo sajt <table></table>, nikakve fensi munje... Da to postuješ negde kod nas na forumu, popljuvali bi te u roku od odmah uz komentar "ništa ne valja, koristiš tabele".

bluesman
01. 02. 2006., 00:57
Moram da nađem neki primer. Koliko se sećam ti si mi pokazivao neke glavne "features" tih layera kao što su na primer generisanje klasa za svaki objekat iz baze.

Generiše se klasa koja ima funkcije tipa:
->getId ()
->setId ()

koja ništa drugo ne radi nego čita iz records polje Id .

Pa onda tako za svaku kolonu iz tabele imaš po jednu get i jednu set funkciju.

Sorry, but this is just plain stupid :)

Pedja
01. 02. 2006., 01:12
Ako sam dobro razumeo mi i jedni i drugi na kraju imamo skup funkcija/klasa/metoda koje rade isti posao. Neke su napisane rucno, neke automatski generisane iz opisa modela baze ali je na kraju rezultat isti.

Jedino sto ne valja u celoj prici to je ako neko mesa SQL i PHP, to jest, pise SQL onde gde mu u PHP-u zatreba umesto da pravi odvojene funkcije sa evenutalno uopstenim parametrima.

Onda je prednost abstraction layer pristupa samo u tome sto on sam izgenerise dobar deo koda. Losa stvar je sto zbog uopstavanja verovatno generise kod koji nije toliko optimalan kao kada bi bio napisan rucno.

Ne bi bilo tesko napraviti php skript koji za postojecu tabelu, pa cak i opisane relacije izgenerisao php funkcije koje rade standardne operacije nad tabelama i to bi verovatno radilo bolje nego klasa koja u letu kreira kod/upit koji treba da izvrsi.

ivanhoe
01. 02. 2006., 04:21
sta ima toliko lose u mesanju SQL-a i PHP-a ?
pa nije to html pa da pises pasuse texta, SQL su skoro uvek one-linersi, a onom ko gleda kod (pod uslovom da zna SQL naravno) je mnogo jasnije o cemu se radi, ako vidi ceo upit...

recimo u mojoj obradi phpLib biblioteke upit izgleda ovako nekako:

$sql = "SELECT id FROM nesto";
$db->query($sql);

while( $db->fetch_next() ) {
$db->echo('id'); // itd...
}

$db je objekat koji se sam poveze na bazu, hvata greske i radi escape promenjivih.....mislim da je to sasvim dovoljno jednostavno, da mi neka dalja apstrakcija apsolutno ne treba. Naravno za neke stvari koje se cesto rade, ok je odraditi zasebnu funkciju da se izbegne pisanje istih upita, tipa:
$a = array('id'=>1, 'ime'=>'pera');
$db->insert('neka_tabela, $a);

ali bas da mora svaki SQL upit da se sakrije u funkciju, mislim da ne mora...

Ilija Studen
01. 02. 2006., 10:34
Onda je prednost abstraction layer pristupa samo u tome sto on sam izgenerise dobar deo koda. Losa stvar je sto zbog uopstavanja verovatno generise kod koji nije toliko optimalan kao kada bi bio napisan rucno.

U osnovnoj liniji da. Ima tu par dodatnih prednosti kao što je odvajanje aplikacije od skladištenja podataka, ugrađeni mehanizmi za keširanje itd.

getX() i setX($value)

Jedna od osnovnih osobina objektno orijentisanog programiranja je enkpsulacija. Ne znam za vas, ali po meni su podaci iz baze podataka sirovi podaci, polufabrikat. Metodi koji omogućavaju pristup ovim podacima (get i set metodi koje blues navodi) pripremaju podatke za korišenje u skriptu, a najtrivijalniji posao koji rade je casteovanje u odgovarajući tip.

Primer kada ovo stvarno dobro dođe smo već imali prilike da vidmo: upgrade baze na Host011 i problem sa TIMESTAMP poljem. Frustracija je bila tolika da je kao rešenje iskorišćen drugi (čistunci bi rekli pogrešan) tip podataka, a jedan od koraka u rešavanju problema je ubijanje nekog odgovornog u MySQLu.

E sad, da je korišćen neki apstrakcioni layer bilo bi dovoljno promeniti način na koji sloj barata sa tim tipom polja na jednom, eventulano dva mesta (unutar baznih klasa) i sve aplikacije koje koriste datu biblioteku ne bi imale nikakvih problema u novom okruženju. Radi kao da se ništa nije ni desilo ;)

Možda sam ja čistunac, ali volim da iz INT kolone dobije integer, iz DATETIME kolone dobije ili timestamp (INT) ili formatirano vreme (proslediš format getteru), iz BOOL kolone dobijem samo TRUE ili FALSE....

Svedi na teoriju programiranja i videćeš da direktan pristup sirovim podacima bez prethodne obrade, međurezulatatima itd predstavlja loš dizajn. Malopre sam naveo i svež primer zašto.

Za nostalgičare

Ako se nekom ne sviđa da koristi $user->getId() implementiranjem ArrayAccess (http://www.php.net/~helly/php/ext/spl/interfaceArrayAccess.html) interfejsa moguće je napraviti da se objekat tretira kao niz, te da bude izvodljivo:

$user = UserPeer::retrieveByPk(12); // Varaća objekat klase User
print $user['id'];

Potpuno čisto OO rešenje za ljude zaljubljene u nizove.

Pedja
01. 02. 2006., 10:35
sta ima toliko lose u mesanju SQL-a i PHP-a ?

- ako SQL izmesas sa PHP kodom, pa naknadno dodje do neke izmene u strukturi ili nacinu obrade, moras da trazis po kodu gde si sve ubacivao upite na koji se te izmene odnose

- SQL cesto nije oneliner, a i ako jeste, obicno ima bar neki promenljivi deo, pa SQL upit u stvari sastavljas u letu, korsiteci PHP, sto je odmh i necitkije. To je bolje odvojiti u zasebnu funkciju, kojoj prosledjujes potrebne parametre, jer tako cinis kod citkijim. Inace sebi pravis veliku komplikaciju koja se nadovezuje na prethodni stav

- Murphy: ako u kodu upotrebis SQL upit na jednom mestu, sasvim je sigurno da ces ga upotrebiti na najmanje jos jednom

- Zlatno pravilo programiranja je pravilo uopstavanja problema. Ma koliko imao ociglednu situaciju koju treba da resis, sasvim je uputno gledati je sire i napraviti kod koji mozes da iskorsitis i u drugim situacijama. Za tvoj primer, recimo, sasvim je logicno napraviti mogucnost da parametrima odredis redosled slogova, broj slogova koji se izvlace iz tabele pa cak i filter jer to ne moze da ti ne zatreba.

Mislim da je ova tema pokrenuta sa stavom da nije pitanje treba li koristiti neki wrapper, nego sta i kako koristiti. Ne valja se vracati unazad, na nacin programiranja od pre procedura i objekata.

Tvoj primer je u neku ruku neobican, jer jedan problem resavas objektnim pristupom, koji je i nastao iz potrebe da se kod pise modularno, uopsteno i da bude upotrebljiv u raznim situacijama a sa druge strane sve te principe potires mesanjem SQL-a direktno u celu pricu.

Naravno, i sam kazes da ovo radi kada su u pitanju jednostavni poslovi, a siguran sam da svako od nas ne preza da ovako napise neki privremeni skript, jer je brze i ociglednije, ali, ako pises kod koji treba da bude u upotrebi dugo vremena, treba da ga odrzavas (ili jos gore, da ga odrzava neko drugi), mesanje SQL-a u PHP je medvedja usluga.

Petar Marić
01. 02. 2006., 10:37
Samo bih voleo da mi neko pokaže jedan abstraction layer, ili kako god ih već zovete, koji će za jednu dobro normalizovanu bazu da napiše query sa 2-3 join-a.
Hm, Django (http://www.djangoproject.com/) ORM?
Primere modela možeš naći ovde (http://www.djangoproject.com/documentation/models/), od kojih bih izdvojio many-to-many (http://www.djangoproject.com/documentation/models/many_to_many/), rekurzivnu many-to-one relaciju na samoga sebe (http://www.djangoproject.com/documentation/models/m2o_recursive2/), i veoma fin primer implementacije category modela (http://code.djangoproject.com/wiki/CookBookCategoryDataModel) koji možeš koristiti u svojim aplikacijama.

A sam db-api će postati znatno lepši (http://code.djangoproject.com/wiki/DescriptorFields) kada "magic-removal (http://code.djangoproject.com/wiki/RemovingTheMagic)" grana bude stabilizovana i uključena u osnovnu distribuciju.

@Ilija vezano sa accessor metode: Jedna od razloga zašto mi se PHP kao jezik/platforma ne dopada je što nema property-e. Umesto ručno pravljenih metoda object.getMember() i object.setMember(value) lepše/lakše/bolje je koristiti property object.member.

Pedja
01. 02. 2006., 10:57
Jedna od osnovnih osobina objektno orijentisanog programiranja je enkpsulacija. Ne znam za vas, ali po meni su podaci iz baze podataka sirovi podaci, polufabrikat. Metodi koji omogućavaju pristup ovim podacima (get i set metodi koje blues navodi) pripremaju podatke za korišenje u skriptu, a najtrivijalniji posao koji rade je casteovanje u odgovarajući tip.

Ovde si potpuno u pravu. I sam sam navikao na objektni pristup, i razmisljam kako bi bilo lepo napraviti klasu, na primer, komitenti, koja ima sve sto moze da ti zatreba vezano za entitet komitent iz baze. U stvari tu klasu ne vidim kao wraper za tabelu komitenti nego nesto vise kao wraper na view nad tabelom komitenti i svim ostalim tabelama koje su sa njom vezane. Medutim, pisati tako nesto je poprilican posao tako da se nikad nisam prihvatio toga da takav mehanizam realizujem.

S druge strane, gledao sam neka resenja kao sto su i ova nesto ranije preporucena, ali mi to sve nekako deluje previse apstraktno, i previse me odvaja od samih podataka. Verovatno kada bih sam napisao nesto takvo, onda bih imao mnogo manji problem sa apstraktoscu.

Ali slazem se, to je definitivno pravac u kome treba razmisljati.

ivanhoe
01. 02. 2006., 14:55
Mislim da je ova tema pokrenuta sa stavom da nije pitanje treba li koristiti neki wrapper, nego sta i kako koristiti. Ne valja se vracati unazad, na nacin programiranja od pre procedura i objekata.

Tvoj primer je u neku ruku neobican, jer jedan problem resavas objektnim pristupom, koji je i nastao iz potrebe da se kod pise modularno, uopsteno i da bude upotrebljiv u raznim situacijama a sa druge strane sve te principe potires mesanjem SQL-a direktno u celu pricu.


pa ok, apsolutno se slazem da treba koristiti db layere, ali pitanje je upravo sta ocekujes da ti layeri rade? Znaci ne samo koji koristiti, nego i zasto bas taj...

Ovaj kod sto sam ja naveo je isto tako vid apstrakcije baze, jedino sto se ne petlja u rad sa samim SQL-om, nego se koncentrise iskljucivo na podrsku propratnih akcija (provere da li vec postoji konekcija, escape parametara u upitu, hvatanje gresaka, free results, debug, konverzija nekih tipova (nrp. timestamp u unix timestamp) i slicno..). Svestan sam da je ovo prilicno konzervativan pristup u odnosu na danasnje trendove, zato sam uostalom i poceo ovu temu...Meni se AdoDB recimo dopao, a svidja mi se i Pear: DB_Data_Object kako radi, ali imam problem da nisam siguran koliko takav visoko apstraktni pristup meni stvarno treba, u poredjenju sa ovom umerenijom apstrakcijom koju sad koristim...

Osnovni problem kod pokusaja da se proces generalizuje (sto je naravno dobra stvar) po mom iskustvu je sto u nekom trenutku funkcija/klasa koju pises pocne da bude preterano komplikovana da bi podrzala svih 200 miliona specificnosti koji mogu da se dese... Ili drugi pristup je da pravis specificnu metodu za svaki taj slucaj, a onda zavrsis sa toliko metoda (obicno slicnih imena) da vise covek ne moze da se seti kad sta koristiti, a one sede u kodu, trose meoriju i skupljaju prasinu...

Mislim da je glavna fora efektivnog programiranja da se oceni kad treba stati sa "uopstavanjem" i neke stvari ostaviti namerno nepokrivenim, jer su retke, a dovele bi do "viska" koda... Najprostiji primer ov logike je ona insert metoda sto sam naveo u proslom postu, ona je super za obicne inserte, das joj niz podataka i ime tabele i ona ih ubaci. E sad sta ako treba umesto konkretne vrednosti ubaciti mysql funkciju (recimo NOW() ), sto cak i nije toliko redak slucaj? To namerno nije podrzano, mada verovatno ne bi bilo komplikovano smisliti dodatni parametar ili regExpom proveriti da li je parametar funkcija. Ali to bi iskomplikovalo postojeci kod i usporilo rad metode koja se cesto koristi, a zarad pokrivanja slucaja koji se redje koristi, a po meni je to losa ideja...

doduse poceo sam da razmisljam ozbiljno da prepevam te phplib klase da podrze i rad sa AdoDB metodama, cisto ako zatreba ponekad... posto priznajem ja da nisu visoko apstraktni pristupi losi za neke situacije...

bluesman
01. 02. 2006., 15:12
Znaš, meni je jedan od osnovnih principa da koristim ono što mi treba, retko radim više od potrebnog, a pisati klase za rad sa Oracle, ODBC, mssql... i čega god možeš da se setiš je po meni jednostavno gubljenje energije i vremena. Naravno, do trenutka kada ti zatreba. A tada, napišeš jednom i imaš zauvek.

Neki imaju princip da koriste "sve gotovo", znači gotove klase za sve živo, skinute sa neta. Ja sam takođe protiv toga iz najmanje 3 razloga:

1. Ne znaš ni ko je pisao ni šta je pisao, par puta sam se opekao kada sam koristio neki tuđi script koji mi je napravio haos.

2. Unutra ima mnogo koda koji ti nije ni potreban

3. Vreme koje utrošiš da se upoznaš sa "novim" sistemom možeš da iskoristiš da napišeš sam ono šta ti treba, na način koji ti treba i tačno onoliko koliko ti treba.

zextra
01. 02. 2006., 15:28
Ja uglavnom sednem pa napisem svoje, bas iz tog razloga sto me mrzi da raspetljavam neciji kod da bih ga razumeo. Ponekad mi se desi da koristim tudji kod bas kao crnu kutiju - ne marim kako nesto radi, bitno je da radi - a iz prostog razloga sto verujem da je kod koji je prosao kroz dosta iteracija i verzija. U boljem slucaju taj kod nije namenjen za neki kompleksan posao, verovatno je dovoljno stabilan i dobro napisan da nema potrebe da izmisljam toplu vodu po milioniti put. Ovo posebno vazi kada mi treba recimo klasa za neki smor posao (tipa crtanje raznih fancy grafikona), i ako vidim da klasa moze da odradi taj posao onako kako mi odgovara - koristicu je, osim u slucaju da mi se ceo posao vrti oko te klase, kada cu se upustiti u analizu iste i eventualno napisati novu, cistiju a mozda i funkcionalniju verziju.

Ilija Studen
01. 02. 2006., 15:43
Skreće se sa teme (moj kod vs gotova biblioteka). Ajd nek neko otvori tu diskusiju već jednom, po Xti put se toga dotičemo. Da ne završi i ova lepa tema u offtopicu :D

bluesman
01. 02. 2006., 15:47
Nije offtopic nego je to prica: sta koristite i zasto.

Ako sam nesto propustio - pokazite mi gde :)

Ilija Studen
01. 02. 2006., 15:56
Znaš, meni je jedan od osnovnih principa da koristim ono što mi treba, retko radim više od potrebnog, a pisati klase za rad sa Oracle, ODBC, mssql... i čega god možeš da se setiš je po meni jednostavno gubljenje energije i vremena. Naravno, do trenutka kada ti zatreba. A tada, napišeš jednom i imaš zauvek.

Sad ćete mi još reći da je mana što recimo PDO ili ADOdb imaju poršku za toliki broj platformi? Neko jednostavno seo, napisao i dao drugima na korišćenje. Zašto moraš da izmišljaš rupu u saksiji iznova i iznova?

To što neka biblioteka ima podršku za veliki broj platformi znači par stvari:

1. Dizajnirana je tako da može da bude specijalizovana na taj način. Sam Factory pattern nije težak za napraviti i ne donosi nikakav značajan pad pad performansi.
2. Dobro i jasno definisan API. Bez toga ovi sistemi ne bi bili mogući ili bi bili jako loši.
3. Dosta ljudi je umešano u razvoj i testiranje tako da je stabilnost datog koda daleko veća nego što bi ti sam mogao da postigneš.
4. Portabilnosti
5. Smanjenje količine koda koju ti sam treba da napišeš, free

Konkretno, svaki od abs layera možeš terati u minimal modu, tj. samo sa podrškom za platformu koja ti treba. Iako dolazi sa malim milionom zapakovanih fajlova, ADOdb zahteva nekih 5 fajlova u minimalnoj instalaciji da bi radio kako treba. U manualu piše šta je sve potrebno za šta i savet kako možeš okresati instalaciju.

Mana je složeniji kod sa padom performansi, ali uz napomenu da ovo u velikom broju slučajeva ne predstavlja problem. Uostalom, zašto koristite PHP? Možete sesti, smisliti rupu u saksiji i svoju novu maestralnu web aplikaciju napisati u C-u ;)

Znam da bar jedna osoba ovde želi da zna koliko tuđeg koda koristim u svom radu. Sorry, ja isto često volim da izmišljam rupu u saksiji tako da od tuđeg koda koristim samo Propel (on koristi Creole). Upoznat sam sa mnogim gotovim biblioteka jer volim da analiziram tuđa rešenja. Tako dolazim do dobrih i proverenih ideja, gledam gde su greške, šta se može uopštiti, a šta izbaciti itd.

Možda mali dodatak, da ne dođe do zabune: stvari kao što su singleton, factory, strategy, activerecord, decorator, facade i tako dalje su imena patterna, ne imena gotovih biblioteka (osim ActiveRecorda gde se najpoznatija Ruby implementacija ovog patterna upravo tako zove). Neki korišćenje ovih termina mogu gledati kao preseravanje, ali je činjenica da se pomoću njih može predstaviti kompletan jedna koncept uz pomoć jedne do dve reči.

degojs
01. 02. 2006., 16:38
bluesman
Znaš, meni je jedan od osnovnih principa da koristim ono što mi treba, retko radim više od potrebnog, a pisati klase za rad sa Oracle, ODBC, mssql... i čega god možeš da se setiš je po meni jednostavno gubljenje energije i vremena.

Upravo i koristimo ove alate da bi mi manje pisali..

U čemu je fazon da ja sad treba da pišem za svaku od 50 tabela u bazi podataka - da za svaku treba da pišem INSERT, DELETE, SELECT i UPDATE izraze? Koliko je to cimanja, ako se zna da pola od tih tabela ima 30+ polja?

Što je najgore to je dosadno do zla boga. Ma idi bre :)

Jednom kad probaš neke alate iz te kategorije, povratka nazad nema.

JOINs? Šta sa njima, tačno? Definiše se potrebni VIEW u bazi, a onda opet dobijemo klasu da pozovemo ovaj pogled.

Što se kvaliteta tuđih alata tiče, zavisi šta se koristi. Neka rešenja su proverena do bola i pouzdano rade u svim situacijama.

Performanse? Nisam siguran da ima problema, ima li ko kakav test?


Nego Gorane, da vidimo konkretno.

1. Imaš tabelu sa 40 polja.
2. Imaš jednu stranicu na kojoj korisnik unosi podatke za polja te tabele
3. Imaš drugu stranicu gde trebaš da prihvatiš unete podatke i spremiš u bazu

Kako ti to radiš?

Pedja
01. 02. 2006., 19:20
Osnovni problem kod pokusaja da se proces generalizuje (sto je naravno dobra stvar) po mom iskustvu je sto u nekom trenutku funkcija/klasa koju pises pocne da bude preterano komplikovana da bi podrzala svih 200 miliona specificnosti koji mogu da se dese... Ili drugi pristup je da pravis specificnu metodu za svaki taj slucaj, a onda zavrsis sa toliko metoda (obicno slicnih imena) da vise covek ne moze da se seti kad sta koristiti, a one sede u kodu, trose meoriju i skupljaju prasinu...


Sta je bolje, imati 200 specificnosti isprogramiranih koje kude po kodu aplikacije (a verovatno i ponavljanih) ili imati te iste specificnosti isprogramirane kroz jednu klasu (ili grupu wraper funkcija). Posao programiranja je manje vise isti, u jednom slucaju programiras na licu mesta, gde se zadesi potreba, a u drugom to isto programiras, ali na uredjen nacin, koji ti omogucuje da na neki nacin stvar organizujes, uvidis mogucnosti uopstavanja i najcesce da isti kod upotrebis na vise mesta. Nema tu viska koda koji gura prasinu. To je isti kod, samo drugacije organizovan i iskoriscen manje ili vise efikasno.


Mislim da je glavna fora efektivnog programiranja da se oceni kad treba stati sa "uopstavanjem" i neke stvari ostaviti namerno nepokrivenim, jer su retke, a dovele bi do "viska" koda... Najprostiji primer ov logike je ona insert metoda sto sam naveo u proslom postu, ona je super za obicne inserte, das joj niz podataka i ime tabele i ona ih ubaci. E sad sta ako treba umesto konkretne vrednosti ubaciti mysql funkciju (recimo NOW() ), sto cak i nije toliko redak slucaj? To namerno nije podrzano, mada verovatno ne bi bilo komplikovano smisliti dodatni parametar ili regExpom proveriti da li je parametar funkcija. Ali to bi iskomplikovalo postojeci kod i usporilo rad metode koja se cesto koristi, a zarad pokrivanja slucaja koji se redje koristi, a po meni je to losa ideja...


Fleksibilnost i kompromisi su uvek bili tajna uspeha. Meni se cini da treba iskoristiti prednosti svakog pristupa i apstrakciju uraditi na bar dva nivoa.

Prvi je onaj koji si ti prikazao u primeru: klasa koja obavlja sve one standardizovane procedure nad tabelema i podacima. Bilo bi idealno kada bi toj klasi mogao da "nacrtam" model baze a da mi ona obezbedi sve potrebne mehanizme pocev od kreiranja same baze pa do standardnih funkcija.

Drugi nivo su klase koje nasledjuju osnovnu klasu u prosiruju je specificnostima potrebnim za konkretnu namenu. One bi po pravilu sadrzavale rucno pisan kod.

Tako imas mogucnost da radis onako kako ti u trenutku odgovara, mozes da uopstavas, ako mislis da je potrebno, a i ne moras jer imas prostora da za specifican problem napises i specifican kod.

Ono sto ces sigurno dobiti to je citkiji kod, koji je lako pratiti i odrzavati.


Sad ćete mi još reći da je mana što recimo PDO ili ADOdb imaju poršku za toliki broj platformi?

Taman posla, dobro je to i lepo, ali biblioteke prosto ne mogu da pokriju sve i uvek postoji potreba da se napis eneki custom kod. Tog momenta portabilnost pada u vodu, jer ja uopste necu da se smaram sa tim da pisem kod koji ce da radi na 16 baza, od kojih samo dve-tri poznajem dovoljno da bih eventualno mogao da razmisljam o podrsci za njih.


Uostalom, zašto koristite PHP? Možete sesti, smisliti rupu u saksiji i svoju novu maestralnu web aplikaciju napisati u C-u

Joj, nemoj mi stajati na zulj. Upravo tako nesto radim, pravim novi jezik koji ima istu funkciju kao i PHP. Razlika je samo sto je drugi jezik. U stvari i ne zalim se, prilicno je interesantno, kao da sam prosao kroz ogledalo pa sad ceo problem vidim "s one strane".

degojs
01. 02. 2006., 19:53
jer ja uopste necu da se smaram sa tim da pisem kod koji ce da radi na 16 baza

1)
To što alati podržavaju 20 baza, ne znači da ćeš ti u svojoj aplikaciji obavezno da koristiš kod koji može da radi sa 20 baza podataka. Ti ćeš od tih 20 podržanih baza da odabereš jednu i dobiješ klase specifične za tu bazu (i tvoje tabele).

2)
Uostalom kakvo smaranje sa pisanjem koda za 16 baza, sve i da imaš potrebu da radiš sa 16 baza? Ko to radi tako? Gde?

Programira se "against interface", tako da te uopšte nije briga koje klase se koriste. Bitno je da sve te klase podržavaju isti interfejs tako da onda za tebe nema razlike da li u pozadini koristiš klasu koja radi specifično sa Oracle 9i ili MySQL 5. U pitanju je Factory design pattern.

Možda i grešim ako si pričao samo za PHP - možda tamo moraš da se smaraš sa pisanjem različitog koda za svaku bazu. Ne znam za PHP, ali znam gde ne mora tako.

ivanhoe
01. 02. 2006., 22:05
opet se vracamo na istu pricu, upotreba vise baza....ako ces uvek koristiti istu bazu, onda ce i interfejs koji koristis da bude uvek isti sve da koristis i obicne drajvere za bazu direktno.

Znaci ajde za sekund da pretpostavimo da imam mysql i da nikad necu koristiti nista drugo. Ako zanemarimo apstrakciju baze koje su onda prednosti upotrebe abst. layera ?

Degojs rece kako oni skracuju vreme kad imas dosta tabela, pa za svaku treba da se pišu INSERT, DELETE, SELECT i UPDATE i kako je to cimanje bez apstrakcije?

E sad meni nije jasno (mislim zaista ne znam, pa pitam) kako i koliko ti automatski generisane klase pomazu u tom slucaju? Koliko moze jedna automatski generisana DB abstraction klasa da ti ustedi truda?

Iz primera imam utisak da ti i dalje moras da znas koji objekat da instanciras (za svaku tabelu ima jedna klasa ako sam dobro shvatio?), a i onda da pozoves odredjenu metodu i kazes joj sta i sa kojim poljima da uradi. Meni se to cini kao drugaciji vid zapisivanja istih stvari koje bi radio iz SQL-a, i cini mi se da to moras da uradis za svaku tabelu, i za svaku akciju nad njom, bas kao i sa SQL-om, right?

u cemu je onda usteda? Ajd pls. dajte neki primer, jer ne kapiram...


A nije bas svejedno kolika je klasa koju koristis, jer na primer AdoDB ima footprint od 700KB sto nije bas malo, pogotovo ako ti skripta samo radi jedan select * from tabela

degojs
01. 02. 2006., 23:03
Samo da ukratko razjasnim o cemu ja tacno pricam, posto je na temi bilo reci o vise stvari.

Sto se mene tice: ja nisam jos imao priliku da radim nesto gde se menja baza (imao sam i imam priliku da radim sa vise baza na jednom sistemu; nebitno za ono sto sam imao na umu). Ima nagovestaja da cu uskoro prvi put i to da radim, ali o tom kad se desi :)

Dalje, ja ne pricam o alatima za mapiranje objekata u relacionu bazu. Nisam to nikad radio te i to preskacem.

E ono sto JESAM radio jeste otprilike ovako: nove tabele u bazi - oko 50 tabela, pola od njih ima 30+ polja.

Iz primera imam utisak da ti i dalje moras da znas koji objekat da instanciras (za svaku tabelu ima jedna klasa ako sam dobro shvatio?), a i onda da pozoves odredjenu metodu i kazes joj sta i sa kojim poljima da uradi. Meni se to cini kao drugaciji vid zapisivanja istih stvari koje bi radio iz SQL-a, i cini mi se da to moras da uradis za svaku tabelu, i za svaku akciju nad njom, bas kao i sa SQL-om, right?

Da, ako sam dobro razumeo. Za svaku tabelu/pogled imas jednu klasu.

Pazi sad, da ja dobijem mogucnost da iz aplikacije radim UPDATE/INSERT/DELETE/SELECT svake od tabela (kao i komplikovaniji SELECT) meni je potrebno, jednom kad su tabele (i pogledi, ako treba) u bazi gotove, tacno nekih 30 sekundi dok program generise te klase. I gotova prica.

Koliko je tebi vremena potrebno da za svaku tabelu imas istu funkcionalnost? Da je kod konzistentan, cist, pregledan i DOBRO testiran?

Ej bre, znas li koliko tu ima fizikalisanja?? I onda jos gledaj da nisi neko polje preskocio..? Zato i pitam: kako bi ti to uradio, koliko vremena bi ti trebalo?

Kad ovo odgovoris, idemo dalje, nije tu kraj price: zato sam i pitao Gorana kako bi on uradio onaj slucaj koji sam opisao. Sve sa malo koda, jer mi se cini da vi olako preskacete neke detalje koji, bar mene, smaraju do zla boga.

ivanhoe
02. 02. 2006., 01:54
Pazi sad, da ja dobijem mogucnost da iz aplikacije radim UPDATE/INSERT/DELETE/SELECT svake od tabela (kao i komplikovaniji SELECT) meni je potrebno, jednom kad su tabele (i pogledi, ako treba) u bazi gotove, tacno nekih 30 sekundi dok program generise te klase. I gotova prica.


uf, meni i dalje nije najasnija razlika, ali ajde bolje da krenemo sa malo primera koda, tako ce biti jasnije...so I'll show you mine and then you show me yours :)

Sa bibliotekom koju trenutno koristim, a koja je vrlo slicna phpLib postupak je otprilike:

$db->query('neki_sql');

gde je 'neki_sql' INSERT, UPDATE, ALTER TABLE ili koji god sql query mi treba... Ako radim SELECT onda bi jos trebalo da pokupim rezultate sa :
while ( $db->fetch_next()) { ... }
ili sa
$a = $db->fetch_all();

Sama klasa brine o tome da se (na osnovu podatak iz config fajla ili direktno propertija nasledjene klase) poveze na bazu (ako vec nije povezana), da uhvati greske(poziva registrovanu callback funkciju), da oslobodi resurse kad nisu potrebni, a postoji i varijanta query metode u kojoj radi escape promenjivih:

$sql = "SELECT * FROM nesto WHERE id=? AND ime='?' ";
$db->query($sql, 1, 'pera');

ovo je moj dodatak koji naprosto uradi escape parametara i zameni ih umesto ? u sql upitu (nije pravi sql prepare, jer php drajveri ne podrzavaju to...)

sa $db->num_rows ili $db->affected_rows moze da se proveri koliko je rezultata, odnosno promena izvrseno...

I onda tako za svaku potrebnu operaciju nad svakom tabelom... koliko ce ovo biti citljivo zavisi naravno od komplikovanosti SQL upita (na webu obicno nisu preterano komplikovani), a i od toga koliko onaj ko cita zna SQL :)

Ajd sad please daj da vidim kontra primer, kako ovo uraditi jednostavnije... ja i trazim nacin da ustedim vreme, zato sam i zapoceo celu pricu...

degojs
02. 02. 2006., 02:56
Nemoj ti meni najjednostavniji primer sa SELECT * WHERE a=b AND c=d, nego daj lepo da vidim primer za INSERT i UPDATE u tabelu gde imamo 30 polja. Ja uporno ponavljam "veci broj tabela, tabele sa vise polja" a ti meni "Evo ti SELECT *" gde prakticno nije ni bitno koliko polja ima :)

Hajde lepo, tabela ima 30 polja. Da vidimo INSERT, da vidimo UPDATE. Pa onda to ponovi 25 puta, za 25 raznih tabela. Hajde da vidimo da li je smaranje ili nije.

1. na prvoj stranici ima recimo 30 polja u koje korisnik unosi neke tamo leve podatke

<form .... >
<input type="text" name="prezime" ...
<input ...
..
</form>

i tako recimo 30 komada, mozda neki <select> i sta vec treba.

Kako kod tebe izgleda druga stranica koja ce da prihvati podatke i doda novi zapis u tabeli u bazi?

Kod mene, evo kako bi to izgledalo u Javi, ovo je citava stranica:

<jsp:useBean id="customerDataForm" scope="request" class="formBeans.CustomerDataFormBean" >
<jsp:setProperty name="customerDataForm" property="*" />
</jsp:useBean>
<%
int customer_id = customerDataForm.insert();
%>


A da sam trebao update samo bi bilo:

boolean OK = customerDataForm.update();


Pazi bre, ja niti sam klase kreirao, niti sam pisao SQL. I tako moze za svaku tabelu. Samo sam napravio tabele u bazi.

Ako moze i kod tebe ovo isto, a drugacije, pricaj :) Meni je ovo bre usteda i vremena i zivaca.

bluesman
02. 02. 2006., 03:36
Nego Gorane, da vidimo konkretno.

1. Imaš tabelu sa 40 polja.
2. Imaš jednu stranicu na kojoj korisnik unosi podatke za polja te tabele
3. Imaš drugu stranicu gde trebaš da prihvatiš unete podatke i spremiš u bazu

Kako ti to radiš?

Raspisali ste se, ja kao sve "kasnije ću na miru da pročitam", a ono sve više. Dakle:

Ako tabela ima 40 polja, onda nešto nije u redu sa tom bazom, fali joj malo sređivanja :) Ili radiš sajt za neku kladionicu :) Pa čak i ako ima, koliko ima takvih tabela? 1 u 10 godina? No dobro...

Ja sam napravio svoju klasu koja ne samo da radi te poslove tipa INSERT, UPDATE automatski nego generiše formulare, generiše server I client side error control (client: javascript, pre submit).

Znači korisnik klikne na submit, ja u kodu imam nešto ovako:

if ($FORM->validate())
{
$q = $FORM->getInsertQuery ();
}


ili getUpdateQuery ();
ili getDeleteQuery ();

i onda izvrsim query koji je u stringu - posaljem ga DB klasi.

Znači, ovo je odgovor na "kako ti to radiš", ali mislim da namerno skrećeš sa teme. Niko ovde (odnosno, bar ne ja) ne priča o ovakvim query-jima. Ja govorim recimo o situaciji:

$sQuery = "SELECT c.*,
f.forum_id, f.cat_id, f.forum_name, f.forum_description,
COUNT(t.topic_id) AS TopicCount,
SUM(t.topic_views) AS ViewCount,
SUM(t.topic_replies) AS RepliesCount,
MAX(t.topic_timestamp) AS LastPost
FROM ".TBL_FORUMS." AS f
LEFT JOIN ".TBL_CATEGORIES." AS c ON (c.cat_id = f.cat_id)
LEFT JOIN ".TBL_TOPICS." AS t ON (t.forum_id = f.forum_id)
GROUP BY f.forum_id
ORDER BY c.cat_order, f.forum_order";


Koji "automatizam" moze da ti generise ovakav query ? Verovatno moze, ali moras da se ubijes i da potrosis gomilu vremena da izdefinises relacije, views... kako god ih zoves.

Pored toga, vecina stvari se cesto ponavlja, tako da recimo ako jednom napravis klasu users gde se on loguje, menja podatke, pretrazuje usere... onda je posao oko novog sajta samo da prekopiras klasu koju imas i eventualno dodas ili oduzmes par polja koja su specificna za odredjeni sajt.

I kažeš cimanje pisati sve te INSERT, UPDATE... Slažem se da je dosadno, ali veće je cimanje definisati tabele kao neki XML ili šta god, pa onda definisati relacije, pa views, pa ovo-ono (pri tom, uvek dođe do neke izmene kasnije pa moraš da predefinišeš relacije pa sve ponovo), pa onda to provaličit kroz neki kod koji će da generiše drugi kod koji bi trebao da radi sa nečim trećim... Koja je tu ušteda u vremenu ili trudu? A pokrenuo si ne samo artiljeriju nego i strateške bombardere i nuklearni arsenal da nebi pisao par querija koje si mogao da napišeš za kreće vreme nego što si napisao postove na ovoj temi.

I non sto pričate o portabilnosti. Nice. Ali, WTF? Koliko puta si morao da portuješ nešto na drugu platformu? Once in a lifetime? Hajde da čujemo koliko ljudi je portovalo nešto na drugu platformu gde mu se isplatio portabilan kod? Možda par? Možda ni jedan.

degojs
02. 02. 2006., 03:54
Ako tabela ima 40 polja, onda nešto nije u redu sa tom bazom, fali joj malo sređivanja Ili radiš sajt za neku kladionicu Pa čak i ako ima, koliko ima takvih tabela? 1 u 10 godina? No dobro...

Je l' da?

Jesi radio nekad aplikaciju koja radi sa pacijentima, bolestima, nalazima, simptomima, tretmanima, epidemijama i slično?

Forme na kojima radimo dobivamo direktno iz prakse. Otkud znam, možda bezveze popunjavaju formulare i slično. Eh sad.. možda smo i mi i oni ludi, a možda ti ne znaš tačno šta i kako to izgleda..

Čak smo i, naravno, forme gde je god bilo moguće "obrnuli" u tabelama tako da se dinamički generišu iz redova u tabeli, a ne kolona.

Eh.

Ja sam napravio svoju klasu koja ne samo da radi te poslove tipa INSERT, UPDATE automatski nego generiše formulare, generiše server I client side error control (client: javascript, pre submit).

Pa jebi ga, ti napravio svoju klasu, a ja koristim nečiju aplikaciju koja radi to isto :)

Onda i pričamo o istoj stvari. Ostaje da vidimo kako ivanhoe radi ovo isto :)

degojs
02. 02. 2006., 04:01
Koji "automatizam" moze da ti generise ovakav query ? Verovatno moze, ali moras da se ubijes i da potrosis gomilu vremena da izdefinises relacije, views... kako god ih zoves.


Pa to jeste view. I za njega cu da dobijem klasu, a njega cu naravno prethodno sam da ili dizajniram vizuelno ili napisem. Pa nece bas alat da mi pogadja misli. E ako si to trazio, pa toga jos nema :)

bluesman
02. 02. 2006., 04:07
Ne znam da li sam ja umoran ili ti? Naravno da nisam očekivao da mi pogađa misli, upravo sam ti pričao o vremenu potrošenom za definisanje svih parametara, views, kako god, i kažem da za mnogo kraće vreme, možeš da napišeš ovaj query (naravno, pod uslovom da znaš sql :) siguran sam da mnogi idu na te "layere" i "generatore" baš iz razloga što ne znaju SQL)

bluesman
02. 02. 2006., 04:12
Jesi radio nekad aplikaciju koja radi sa pacijentima, bolestima, nalazima, simptomima, tretmanima, epidemijama i slično?

Pu - pu - pu, ne daj Bože :)

Nisam ali sam radio sa kladionicama, znaš ono 1-1, 1-x, 1-2, ... pa golovi prvo poluvreme, pa golovi kraj, pa tačan rezultat... pa prvi daje gol, pa korneri, pa ...

Ali ovo tvoje zvuči kao idealan slučaj za lepo normalizaciju, ali nećemo o tome sada.

degojs
02. 02. 2006., 04:19
Odustajem, jer mislim da ne razumes viewe uopste:
upravo sam ti pričao o vremenu potrošenom za definisanje svih parametara, views, kako god, i kažem da za mnogo kraće vreme, možeš da napišeš ovaj query

Ama covece taj query JESTE view.

Ajd sad da pitam: jesi li pravio view u nekoj bazi? Nisi. Da jesi, znao bi da je to sto si otkucao, taj query, isto ono sto bi otkucao u nekoj bazi i sacuvao tamo kao npr. "view1". I onda mozes recimo SELECT * FROM VIEW1 WHERE..


Inace, kod mene je 22:15, bice da si ti umoran :)

degojs
02. 02. 2006., 04:23
Ali ovo tvoje zvuči kao idealan slučaj za lepo normalizaciju, ali nećemo o tome sada

Znas, sad si vec i bezobrazan (tipa znam ja da to moze bolje iako pojma nemam o cemu se tamo radi, ni da li je vise ljudi ukljuceno koji imaju bas mnogo iskustva i slicno, ni da li su merene performanse, ni da li je radjena normalizacija pa *denormalizacija* /znas li zasto se radi denormalizacija?/, itd).

Ebi ga, al malo zajebavas :)

ivanhoe
02. 02. 2006., 07:10
Onda i pričamo o istoj stvari. Ostaje da vidimo kako ivanhoe radi ovo isto :)

kul je ovaj JSP... :)
Mada ovaj tvoj priemr je vise zgodan zbog validacije forme, nego sto je nesto velika usteda oko inserta...a koliko je meni u znanju ni jedan DB abstraction za php4 ne nudi nista na ovu foru...

a sto se tice toga kako ja to radim, ja uglavnom koristim php i mada ima u php-u brdo gotovih klasa za validaciju, ja to obicno radim od slucaja do slucaja, jer mi retko treba vise od 10-tak polja po formi, a za to copy&paste radi posao... a sem toga ionako neka malo slozenija pravila kao validaciju email-a, CC-a ili zip kodova moras da pises rucno...

a sam insert sam vec jednom pisao, otprilike ovako:

$err_arr = validate(); //validacija forme
if( !is_array($err_arr))
$db->insert('ime_tabele', $_POST); // insert

umesto $_POST moze bilo koji hash kome su kljucevi imena polja u bazi...tvoje java resenje jeste krace i lepse, ali nije to bas tako strasno komplikovano ni ovako...naravno da moram da obradim 50+ polja po formi verovatno bi mi dobro dosao neki Pear DB_Data_Object ili Propel ili vec neka teska artiljerija...


i da se razumemo nemam ja nista protiv fancy DB abstraction layera, bas naprotiv ja bih rado da uzmem da koristim neki dobar (jer ovo sto ja koristim datira jos iz php3 i sigurno moze bolje da se odradi), ali mi smeta kod vecine sto su preglomazni, a pritom pola opcija koje nude mi ne trebaju. Ja bih neki jednostavan, brz, a funkcionalan... koristiti ove postojece na obicnim sajtovima je kao voziti porshea po beogradu, neces moci da primetis neku realnu prednost, osim sto je fancy i trosi vise..

Cisto kao mali primer moje logike, na sajtu AdoDB Lite mozete da vidite benchmarke koji pokazuju da je AdoDB oko 5 puta sporiji od cistog mysql-a (bez akceleratora, ali to je uobicajen slucaj)... a plus zauzme nekih 700KB memorije samo kad se includuje...to nije bas zanemarljiva stvar, priznacete?

Ilija Studen
02. 02. 2006., 07:36
DB abstraction za php4 ne nudi nista na ovu foru...

CakePHP bi trebalo da ima relativno kompletno implementiran ActiveRecord sa validatorima što znači da se generisanje i validacija formi rade (polu)automatski. U Railsu (Cake je pravljen po uzoru na njega) je sve automatizovano tako da je pitanje koliko su phpnut i kompanija (CakePHP dev tim) dogurali u portovanje.

U Propelu (PHP4 i PHP5 generator) imaš mogućnost setovanja validatora (sprečavaju insertovanje / update objekta sa neispravnim svojstvima), ali ne i podršku za automatsko generisanje / procesiranje formi. To moraš sam da implementiraš ili možeš da "pokradeš" neko gotovo rešenje kao što je Symphony na primer.

ali mi smeta kod vecine sto su preglomazni, a pritom pola opcija koje nude mi ne trebaju

Slažem se. Zato i volim Rails... Uzeli su less everything pristup tako da je sam framework nezagađen. Ima ono što ti treba i nešto sitno preko. Tu se staje... Kamo sreće da ekipa koja radi Propel prihvati ovaj pridtup.

Čak iako sam nezadovoljan kvalitetom mnogih PHP5 rešenja ipak branim stav da je pametnije koristiti ovakve biblioteke nego se igrati sa čistim SQLom kod svih složenijih projekata. Za sitne stvari quick and dirty, za ozbilnije zna se...

---

Pošto je bluesman izjavio da većina koristi ovakve biblioteke kako ne bi morali da koriste SQL iz razloga što ga ne znaju (ovu izjavu u najmanju ruku smatram netačnom) evo malo istorije.

Prvi Windows programeri su morali da znaju Win32 API u dušu da bi radili. Pišu ljudi koji su radili u to vreme da je to jedan izuzetno komplikovan i smoran posao. Nisam probao tako da moram da im verujem na reč. Kako je vreme prolazilo, tako su alati sazrevali da bi danas koristio proste drag and drop metode za kreiranje formi, gotove biblioteke za rad sa prozorima i kontrolama itd itd itd. Sam API retko ko koristi, sve se radi kroz wrappere. Možda grešim u nekim detaljima, nisam se bavio programiranjem u to vreme tako da mogu da pričam iz prve ruke. Samo želim da istaknem da se programiranje razvija u tom smeru da skraćuje vreme koje programer treba da uloži u prljav, vodoinstalaterski posao (jer SQL to uglavnom jeste) i omogući mu da se više koncentriše na konkretan problem koji treba da reši, stvari unikatne za projekat.

Slična stvar se desila i sa SQLom na ozbiljnim platformama (.NET, Java, Delphi...), a polako niču projekti koji portuju rešenja sa tih platformi (Propel je u suštini PHP verzija Torque (http://db.apache.org/torque/) projekta) ili osmišljavaju i implementiraju nova na "neozbiljnim" platformama.

---

Ne znam da li da pokazujem jedan jednostavan Rails primer pošto mislim da je kod njega iskorišćen jedan od lepših pristupa? ActiveRecord je stvarno lepo napravljen.

zextra
02. 02. 2006., 11:51
Retko dobra diskusija. thumbs up! :)

bluesman
02. 02. 2006., 12:05
Odustajem, jer mislim da ne razumes viewe uopste:

Ama covece taj query JESTE view.

Ajd sad da pitam: jesi li pravio view u nekoj bazi? Nisi. Da jesi, znao bi da je to sto si otkucao, taj query, isto ono sto bi otkucao u nekoj bazi i sacuvao tamo kao npr. "view1". I onda mozes recimo SELECT * FROM VIEW1 WHERE..

Inace, kod mene je 22:15, bice da si ti umoran :)

Možda ja ali možda i ti :). Naravno da znam šta su views, na to sam i mislio ali očigledno se ne razumemo. Hteo sam da upitam šta ti dobijaš time što definišeš posebno relacije da bi generisao view-ove na koje potrošiš više vremena, pa onda ih koristiš tako "definisane" u odnosu na jednostavno izvršenje querija. Ne vidim nikakvu uštedu.

Vidi, one jednostavne query-je ja obično nazivam "hleb i mleko". Zato sam i pravio klasu koja će da mi taj proces automatizuje. Sve što je iole komplikovanije (obično i gotovo isključivo su to SELECT) mora da se piše ručno. Ono što pokušavam da kažem da ne postoji način da se proces automatizuje, najbolje što možeš je poluautomatski, znači jednostavno - automatski, komplikovano - ručno. Samim tim pada u vodu cela priča o automatizmu čitavog procesa. A izvlačiti čitav arsena teške artiljerije zbog "hleba i mleka" po meni nije optimalno rešenje.

Pedja
02. 02. 2006., 12:19
bluesmane, mislim da bi morao svoje tvrdnje da potkrepis time sto ces tu tvoju biblioteku da stavis u attachment :D

degojs
02. 02. 2006., 14:29
Hteo sam da upitam šta ti dobijaš time što definišeš posebno relacije da bi generisao view-ove na koje potrošiš više vremena, pa onda ih koristiš tako "definisane" u odnosu na jednostavno izvršenje querija. Ne vidim nikakvu uštedu.

Kako to definisem posebno relacije da bi generisao view-e?

bojan_bozovic
02. 02. 2006., 23:43
Do GPL 3. A onda cemo morati sami da pisemo kod.

bluesman
03. 02. 2006., 01:02
degojs: Ti si nekako uspeo da se ubaciš na pola priče, nisam siguran da znaš i history, stvar je u tome da su neki tvrdili kako ima je lakše da postupe otprilike ovako:

Naprave XML (ili neku alternativu) sa strukturom baze
Provuku taj XML kroz neku klasu koja im izgeneriše druge klase
Onda imaju sistem koji im omogućuje da ne pišu te osnovne querije
Zatim, za bilo šta ozbiljnije, imaju poseban sistem u kojem opet moraju da navedu tačne relacije u bazi, ključeve, posebne "view"-ove (ne ono na šta ti misliš), pa onda to tako opet provlače kroz neke scriptove koji ime opet generišu neke kodove koji im omogućavaju da se "ne zezaju sa mysql".

Po meni, svako radi kako mu odgovara, priča je o tome da to olakšava život. Ja tvrdim da je utrošeno vreme i energiju moglo efikasnije da se iskoristi, cela priča je samo o tome.

Znači ne pričamo o mogućnostima mysql, evo, prvi post je krenuo ovako:
Jako se mnogo prica o portabilnosti koda sa jedne baze na drugu, ali nisam siguran koliko to prakticno ima znacaja? Da li vam se ikada desilo da ste naknadno morali da portujete neki web projekat sa jedne baze na drugu?

a pitanje koje je lajtmotiv je: Koje je vase misljenje o tome da li se isplati koristiti abstraction layere uopste?

uz direktno pitanje: "Kakva su vasa iskustva?"

Ne bih sada da ponavljam, ionako sam već nekoliko puta u ovoj temi, svoja iskustva po tom pitanju, kao i svoje stavove, samo podsećam na glavni tok.

degojs
03. 02. 2006., 01:54
Pa ja sam iz tog razloga i napisao u svojoj, cini mi se drugoj, poruci o cemu ne pricam (ORM i sta-ti-ja-znam-sta).

Dalje, ovo sto mi koristimo (MyGeneration (koji podrzava cini mi se i PHP) i jos jedan alatcic "in-house-made") omogucuje mnogo vise (i sutra ako bi trebali da promenimo bazu, a necemo, ne bi imali nikakvih problema - svoj kod ne bi morali da menjamo, znaci imamo apstrakciju!), ali niti nas je briga za to, niti nam pada na pamet..(jeste, nesto se suska da bi mogli da menjamo jednu bazu, ali o tom kad bude..)


E sad, sto ovaj tu jedan voli da mnogo prica o stvarima o kojima je verovatno samo citao.. kao da mi nismo culi za ORM, kao da i mi ne bi mogli da trubimo do zore.. Ali ja sam, kako rekoh, lepo napisao da o tome ne pricam.

A evo sta kazu na sql2Java stranici, komentarisu verovatno najpoznatiji i najpopularniji ORM alat na Javi - Hibernate:

The point is that this kind of software is great, often technologically speaking they are damn great, but their learning curve are damn steep, and when an exception arise, you are damn lost ...

Meni se manji i laksi alati mnogo vise svidjaju, a za alatima kao sto je Hibernate jos nisam imao potrebe, jer jos nisam radio aplikaciju gde se krece sa druge strane (od objekata, a ne od baze).

Ilija Studen
03. 02. 2006., 05:39
degojs, dolaziš iz potpuno drugog "sveta".

Začudio bi se koliko PHP programera ne zna šta su ovakve biblioteke, da postoje, kako rade, da su odlično testirane i stabilne, koliko vremena štede itd itd. Samo uzmi činjenicu da većina još nije prešla ni na PHP5 gde se tek može pričati o pravom OOP. Svest većine PHP programera o patternima, naprednim OO konceptima itd je uglavnom jako ograničena... Ono što je u Javi potpuno normalno u PHPu je uglavnom novotarija i "preseravanje".

No, to je sad već potpuno drugačija priča.

Proces o kome blues priča je nasleđen od Java ekipe pošto je prvi Propel bio čist port (čovek nije želeo da izmišlja toplu vodu). Odluku da se koristi XML kao jezik za opisivanje u neku ruku i odobravam, ali potreba da se korist build alat (PHP port Anta) je skroz debilna po meni. Možda je u Javi normalno koristi build alate, ali u PHPu definitivno nije...

To na stranu, način na koji ga je blues opisao zvuči kao da je to pola sata posla, što je daleko od istine. Sam proces se može podešavati tako da se izmene rade brže nego što neko može da otkuca jedan malo složeniji upit...

ivanhoe
03. 02. 2006., 06:19
Samo želim da istaknem da se programiranje razvija u tom smeru da skraćuje vreme koje programer treba da uloži u prljav, vodoinstalaterski posao (jer SQL to uglavnom jeste) i omogući mu da se više koncentriše na konkretan problem koji treba da reši, stvari unikatne za projekat.

Slična stvar se desila i sa SQLom na ozbiljnim platformama (.NET, Java, Delphi...), a polako niču projekti koji portuju rešenja sa tih platformi (Propel je u suštini PHP verzija Torque (http://db.apache.org/torque/) projekta) ili osmišljavaju i implementiraju nova na "neozbiljnim" platformama.


Ja sam ranije radio dosta u Delphiju (a cini mi se da se i Pedje secam sa yu.prog.delphi newsa? ) i apsolutno podrzavam taj vid automatizacije koji recimo Delphi pruza. Dovuces par komponenti, popunis par propertija i imas npr potpuno funkcionalni data-grid. Dajte mi to za php i bicu srecan kao kuce, pa makar morao da pozivam objekte da uradim SELECT *... :)

Ali Delphi ti takodje nudi mogucnost i da stvari radis na vrlo niskom nivou, ako treba i asembler da koristis... autori ovih DB klasa koje sam ja imao prilike da vidim ne omogucavaju low-level alternativu i to je po meni problem..

Nije samo da je ponekad naprosto brze i lakse otkucati par sql komandi... ponekad (cak prilicno cesto) je prakticno neophodno iskoristiti neku specificnu foru baze koja zahteva kontrolu koju pruza SQL...

Uzmi recimo "SELECT SQL_CALC_FOUND_ROWS ..." i "SELECT FOUND_ROWS()". Jako korisna stvar da izbegnes dupli upit na bazi kad koristis limit da prikazes samo deo rezultata (paged results), sto ce reci prakticno na svakoj strani gde se nesto lista iz baze. Sa pre-generisanim klasama si osudjen na 2 upita, jedan count(*) i jedan sa limitom...

Ili mozda i kriticnije, cinjenica da kod mysql-a ponekad zavisi koji ce index da se upotrebi (i da li ce se uopste upotrebiti) od redosleda uslova u WHERE klauzuli (to je po meni zapravo bug u query optimizeru, ali sta da se radi..). Kako ces to da kontrolises, ako ti klasa to pravi automatski i jos ti prepakuje tvoj SQL da bude kompatibilan sa 20 drugih baza?


to je jedna vrsta problema, mozda ne toliko bitna za generalnu publiku, jedan upit ili 5 tesko da je bitno, recimo prosecna strana bloga u Wordpressu uradi 30+ upita i opet ga svi srecno koriste (ukljucujuci i mene jer sam lenj..)

drugi ocigledniji problem (koji i mene muci priznajem) je naravno da je potrebno promeniti nacin razmisljanja o bazi za 90 stepeni, sto bas i nije jednostavno ako radis na odredjeni nacin godinama... za mene je SQL najprirodniji nacin obracanja bazi, jer sam tako naucio.. Da sam prethodno radio sa OO pristupom bazi (sto cenim da je po godinama slucaj sa Ilijom) verovatno bi mi se to cinilo kao super stvar u odnosu na kuckanje SQL-a... navika je mnogo gadna stvar...

ja za sada jos uvek skidam i isprobavam razna resenja, cekam nesto sto ce da napravi kompromis izmedju lakoce rada i mogucnosti...we'll see...;)

bojan_bozovic
03. 02. 2006., 07:51
Nisam koristio DB abstractiol layer. SQL? Pa to je jednostavno! Ne znam, ne volim da komplikujem kad moze jednostavno. BTW i performanse su mi bitne, sto se debagovanja SQL tice, samo udrim $querydump=$querydump." ". $query; pri svakom upitu i na kraju echo $querydump i imam i vise debagovanja nego sto mi treba ;) Ne znam zasto da se mucim sa ko zna koliko komplikovanom bibliotekom za vrlo jednostavne stvari. Mozda, da moram da migriram na drugu bazu, ali je to sigurno vrlo pipavo, i opet bih zeleo da to redim rucno. Nemam onda tudji (citaj: bagovit) kod izmedju. Gresim li ja nesto ili je pravjenje XML za DB abstraction lejer isto sto i rucno dizajniranje baze? BTW mislim da je bolje da covek dizajnira bazu nego da imas 80 tabela u potpuno normalizovanom stanju ili sta vec glupi kompjuter moze da napravi. Kompjuter ne poseduje inteligenciju da me zameni u poslu, pa dali sam pravim CREATE upit za tabelu ili to pisem u XML, isto bi trebalo da bude.

PS: Kad moj kod zabrlja, bar znam sta je i gde je. Sa tudjim kodom nije tako, jer nemam dokumentaciju za kod.

degojs
03. 02. 2006., 07:58
Poceli smo i da se ispovedamo, a :)

ivanhoe:
Nije samo da je ponekad naprosto brze i lakse otkucati par sql komandi... ponekad (cak prilicno cesto) je prakticno neophodno iskoristiti neku specificnu foru baze koja zahteva kontrolu koju pruza SQL...

Uzmi recimo "SELECT SQL_CALC_FOUND_ROWS ..." i "SELECT FOUND_ROWS()". Jako korisna stvar da izbegnes dupli upit na bazi kad koristis limit da prikazes samo deo rezultata (paged results), sto ce reci prakticno na svakoj strani gde se nesto lista iz baze. Sa pre-generisanim klasama si osudjen na 2 upita, jedan count(*) i jedan sa limitom...

Nije to problem. Svaki bolji generator daje, je li, sors kod. A ti ga posle izmeni kako hoces. Jos bolje, izmeni sablon, tako da u jednom cugu dobijes rezultate vise upita.
Npr. Java to podrzava bez problema. Vise upita, jedna komunikacija sa bazom, dobijes kolekciju ResultSet-a nazad. Nema problema.

Kako ces to da kontrolises, ako ti klasa to pravi automatski i jos ti prepakuje tvoj SQL da bude kompatibilan sa 20 drugih baza?

Pazi, ovo sto mi koristimo ne daje kod koji moze da radi sa 20 baza "istovremeno", nego kod koji radi sa jednom bazom. Ali ti mozes lako da kazes hocu sad kod za tu drugu bazu pa za 30 sekundi, eto ti koda (optimizovanog) za drugu bazu. Stvar je da kod svoje aplikacije ne moras da menjas.

drugi ocigledniji problem (koji i mene muci priznajem) je naravno da je potrebno promeniti nacin razmisljanja o bazi za 90 stepeni, sto bas i nije jednostavno ako radis na odredjeni nacin godinama... za mene je SQL najprirodniji nacin obracanja bazi, jer sam tako naucio.. Da sam prethodno radio sa OO pristupom bazi (sto cenim da je po godinama slucaj sa Ilijom) verovatno bi mi se to cinilo kao super stvar u odnosu na kuckanje SQL-a... navika je mnogo gadna stvar...

Ajd sad kad vec pricamo..

Nije tu samo to problem. Kod takvog pristupa dosta vremena ode na pocetku na dizajniranje klasa i odnosa medju njima, interfejsi, nasledjivanje.. a to znaci da vidljivih rezultata nema tako brzo. A samim tim ako sve to moras da radis skoro je sigurno da je veliki projekat u pitanju. Pitanje je da li tvoj projekat uopste spada u tu kategoriju.

Sa druge strane, bazu je uglavnom lako uraditi (pogotovo ako ti bluesman ne radi normalizaciju nakon sto si ti normalizovao pa denormalizovao istu ;) ) i mozes da krenes sa front-endom (pogotovo ako imas dobar alat koji ce da ti ustedi sav vodoinstalaterski rad na relaciji front-end <-> baza). I rezultati, makar rada u toku, su brzo vidljivi, a to se cesto jos i trazi.

Mozda ce da bude drugacije kad jos i baze budu podrazumevano nudile tipove podataka a la java.Object, net.Object, php.Object i slicno..

"Doh!" sto bi rekao dinke, ovaj, Homer Simpson.

Pedja
03. 02. 2006., 14:50
ivanhoe:

Ja sam ranije radio dosta u Delphiju (a cini mi se da se i Pedje secam sa yu.prog.delphi newsa? ) i apsolutno podrzavam taj vid automatizacije koji recimo Delphi pruza. Dovuces par komponenti, popunis par propertija i imas npr potpuno funkcionalni data-grid. Dajte mi to za php i bicu srecan kao kuce, pa makar morao da pozivam objekte da uradim SELECT *...


Eh Delphi... moram priznati da je su Turbo Pascal i Delphi nesto ponajbolje sto se dogodilo u mojoj programerskoj karijeri i principe na koje sam navikao u njima primenjujem gde god stignem.

Pogodio si me u zicu, jer je i moj ideal da u PHP imam alat koji omogucava da radim nesto sa tom dozom prakticnosti koju Delphi pruza a uveren sam da kada bi se napravile klase koje funkcionisu na principu Delphijevih objekata, to bi bila odlicna stvar. Zamisli samo tu liniju: TTable|TQuery -> TDataSource -> TDBGrid u PHP-u... pa eventi, koji bi u stvari mogli biti mnogo mocniji, jer su skriptovi, a ne prekompajliran kod, kao u Delphi-ju.

Meni se inace cini sasvim ok da koristim neki vizuelni alat kao sto je DBDesigner4 u kome opisem model baze, a onda tako definisan model koristim da izgenerisem osnovni wraper kod koji mi mora olaksati rad sa tim modelom. Ako bih morao rucno da pisem XML koji opisuje model, pa da, to bi bio sustinski neprihvatljiv pristup.


Nego...

Ova nadasve korisna i interesantna diskusija polako prelazi u nadmudrivanje i teoretisanje pa gubi ostricu.

Sta mislite da uzmemo neki zamisljeni poluslozeni model podataka i da malo prakticno i konkretno poradimo na razlicitim pristupima u apstrakciji?

Ilija Studen
03. 02. 2006., 17:05
Meni se inace cini sasvim ok da koristim neki vizuelni alat kao sto je DBDesigner4 u kome opisem model baze, a onda tako definisan model koristim da izgenerisem osnovni wraper kod koji mi mora olaksati rad sa tim modelom. Ako bih morao rucno da pisem XML koji opisuje model, pa da, to bi bio sustinski neprihvatljiv pristup.

DBDesigner4 čuva šemu u XML obliku tako da se taj dokument uz pomoć jednostavnog stila može transformisati u Propel XML fajl. Više o tome (http://blog.tooleshed.com/?p=6)...

Propel XML fajl se može generisati i na osnovu postojeće baze podataka. Potrebno je koristiti creole target... Samom fajlu su kasnije potrebne sitnije dorade, ali je i to bolje nego pisati ga od nule. Na žalost ne mogu da pristupim Propel sajtu tako da ne mogu da linkujem na tutorijal.

PS: Ja se izvinjavam ako konkretizujem previše. Ovde su uglavnom PHP programeri tako da mislim da ove informacije i linkovi nisu na odmet. Ako ništa, a ono bar da se ljudi koje interesuju upoznaju sa stvarima koje ove biblioteke mogu jer često mogu više nego što se na prvi pogled čini ;)

ivanhoe
03. 02. 2006., 19:31
E bas je dobar ovaj DBDesigner4, nisam ga do sad nikad koristio..

a jel ima on neku caku da se polju u tabeli dodeli komentar (da ne jurim po helpu)

Pedja
03. 02. 2006., 23:23
U verziji koju korsitim jedno od polja koja mozes da popunis prilikom definisanja polja tabele je i komentar.

ivanhoe
05. 02. 2006., 05:30
evo jedne zanimljive (bar meni) price na ovu temu na koju sam slucajno naleteo trazeci nesto peto na sitepointu (da ne ispadne da sam opsednut bazama :P ):

http://www.sitepoint.com/forums/printthread.php?t=82885&pp=200

degojs
05. 02. 2006., 06:25
Ajoj, al je taj što je to pisao blesav..

So if I use database abstracion and write my application for MySQL and then later want to switch to PostgreSQL or Oracle, although I won't have to change most of the method calls in my scripts, I will still have to change almost all of the SQL queries!

Priča o apstrakciji a onda kaže da će da menja SQL kverije. Pa kakvi SQL upiti ako koristiš upravo apstrakciju? Pa on ne razume uopšte ni pola priče.. Koja glupost. Pa ti sistemu treba da kažeš koju bazu koristiš da bi on mogao da koristi kod specifičan za tu bazu, a ne.. da abstraction layer nekom magijom ima SQL kod koji radi na svim bazama. Svašta. Već sam napisao pre, može da se koristi Factory dp.

Dalje nisam ni čitao.

Pedja
05. 02. 2006., 11:45
Trebao si jos malo da citas :) Ono o cemu covek pise ima dosta rezona a mi bas pomenusmo ovde Delphi jer je to njegov rezon i pokazao se veoma mocan i praktican.

Evo cemu se radi, napravis osnovnu klasu koja obezbedjuje uopstene mehanizme za rad sa bazom od kojih su vecina smao definisani ali ne i implementirani.

Onda pravis klasu koja radi sa odredjenom bazom tako sto nasledis osnovnu klasu, obezbedis funkcionalnost za definisane metode a mozes da je prosiris i svojim.

Mozes da napravis i klasu za neku drugu bazu na isti nacin, tako sto nasledis osnovnu, das joj funcionalnost i prosiris je.

Neko sasvim treci, moze da napravi klasu za neku sasvim trecu bazu tako sto ce narpaviti novukalsu nasledjujuci osnovnu.

Osnovna prenost je sto su sve te klase medjusobno kompatibilne, a promena podrzane baze se moze svesti na to da umesto jedne, koristis drugu klasu. naranvo, i dalej ostaje ogranicenje custom SQL upita, koji se ni na koji nacin ne mogu tek tako biti automatski portovani na drugu bazu.

ivanhoe
05. 02. 2006., 11:52
Ajoj, al je taj što je to pisao blesav..



Priča o apstrakciji a onda kaže da će da menja SQL kverije. Pa kakvi SQL upiti ako koristiš upravo apstrakciju? Pa on ne razume uopšte ni pola priče.. Koja glupost. Pa ti sistemu treba da kažeš koju bazu koristiš da bi on mogao da koristi kod specifičan za tu bazu, a ne.. da abstraction layer nekom magijom ima SQL kod koji radi na svim bazama. Svašta. Već sam napisao pre, može da se koristi Factory dp.

Dalje nisam ni čitao.


Covek prica o Pear: DB i AdoDB, najpopularnijim abstraction layerima za PHP, i u jednom i u drugom se pisu SQL queriji direktno... tako da ne prica on gluposti nego ti ne znas kako se to radi u php-u...

Da si procitao ceo text video bi da se prica o ideji da je (po njemu) pogresno bazu asptrakovati tabelu po tabelu, ili query po query, nego treba apstrakcija da bude zasnovana na prirodi entiteta sa kojim radis, tipa imas recimo klasu User i sve sa njom radis, a ne zanima te da li userove podatke cuvas u jednoj ili 5 tabela, to je pitanje implementacije same klase i zavisi, izmedju ostalog i od tipa baze...

to je u stvari ista fora kao da imas View u bazi koji ti joinuje sve podatke za Usera, pa sa njim radis...tebe ne zanima odakle ti podaci dolaze u View, samo te interesuje koje se polje kako zove....

Ilija Studen
05. 02. 2006., 13:16
Postoji velika razlika između apstrakcije pristupa bazi i apstrakcije pristupa podacima. Ljudi kada govore o apstrakcionim slojevima (PHP svet) obično misle na ovo prvo, a trebalo bi da misle na ovo drugo.

$conn = get_connection('mysql');
if(!$conn->connect('localhost', 'root', '', 'test')) die('Ups!');
$result = $conn->execute('SELECT * FROM `products`');

Primer sam lupio iz glave, ali ovo je nešto što većina PHP developera smatra apstrakcijom (i što degojsu izgleda non stop promiče). To je daleko od prave apstrakcije. Samo je defininisan API za komunikaciju sa više različitih baza i par pomoćnih metoda (izvuci sve podatke iz rezultata kao niz nizova i sl).

Prava apstrakcija bi bilo nešto slično ovome:

$user = new User();
$user->setUsername('root');
$user->setPassword('***');
$user->setEmail('mail@somebody.com');
try {
$user->save();
} catch(Exception $e) {
die($e->getMessage());
}

Da li ja znam šta će se desiti? Znam: novi korisnik će biti kreiran sa zadatim podacima. Da li znam gde će i kako podaci biti sačuvani? Ne nužno... To može biti baza, može biti fajl, može biti poslat zahtev nekoj drugoj aplikaciji na drugom računaru da doda korisnika... Uostalom, ne zanima me. Ako nešto pođe na loše biću obavešten o tome.

OK, dodato. Šta dalje?

// Load...
$user = Users::load(12);

// Update
$user->setPassword('*******');
try {
$user->save();
} catch(Exception $e) {
die('Greška pri izmeni. Razlog: ' . $e->getMessage());
}

// Delete
try {
$user->delete();
} catch(Exception $e) {
die('Greška pri brianju. Razlog: ' . $e->getMessage());
}

die('Korisnik uspešno orbisan!');

Jednostavno se u aplikaciji ne brinemo o načinima na koji se podaci skladište već o samom baratanju njima.

PS: Ja stvarno ne razumem zašto ljudi toliko ističu prebacivanje sa jedne na durgu platformu kao osnovnu prednost apstrakcionih slojeva. Taj slučaj je toliko redak da je to nešto što bi trebalo da se nalazi negde pri dnu features liste. Skroz je OK imati tu mogućnost, ali definitivno je ne treba toliko isticati. Ono što je meni najvažnije kod njih je što te oslobađaju vodoinstalaterskog posla na relaciji aplikacija-baza i mogućnost da se u aplikaciji posvetim samom baratanju podacima.

PPS: Sva tri primera su iz glave i služe samo da ilustruju kompletnu priču kroz kod.

zextra
05. 02. 2006., 15:41
Verovatno zbog nepoznavanja terminologije, ja takav nacin rada nazivam "modularni pristup", bas iz razloga sto meni, recimo, sloj za interakciju sa bazom predstavlja poseban modul, koji se automatski ucitava ako ja iz nekog treceg modula pozovem modul User (jer sticajem okolnosti korisnike cuvam u mysql bazi), a koje module on koristi da bi obavio posao apsolutno me se ne tice - koristim njegove metode i tako za svaki pojedinacan modul.

Mislim da se mogucnost transparentne promene db engine-a forsira pre svega sto omogucava developerima koji koriste razlicite baze da koriste isti abstraction layer na potpuno isti nacin kao da koriste bilo koju od podrzanih baza, dakle iz razloga popularizacije istog. A to sto programer koji koristi pgsql verovatno nikad nece hteti da koristi recimo sqlite... Pa, bitno je da ima i tu mogucnost...

Ilija Studen
05. 02. 2006., 15:50
Mislim da se mogucnost transparentne promene db engine-a forsira pre svega sto omogucava developerima koji koriste razlicite baze da koriste isti abstraction layer na potpuno isti nacin kao da koriste bilo koju od podrzanih baza, dakle iz razloga popularizacije istog.

Slažem se, ali preterano isticanje te mogućnosti je dovelo do toga da dobar deo programera gleda na to kao njihovu jedinu svrhu...

zextra
05. 02. 2006., 16:06
I never said it's a Good Thing(tm) :)

degojs
05. 02. 2006., 16:19
ivanhoe
Covek prica o Pear: DB i AdoDB, najpopularnijim abstraction layerima za PHP, i u jednom i u drugom se pisu SQL queriji direktno... tako da ne prica on gluposti nego ti ne znas kako se to radi u php-u...

Dobri su to layeri kad moraš da pišeš SQL... Nebitno da li je PHP ili nešto drugo.

Da si procitao ceo text video bi da se prica o ideji da je (po njemu) pogresno bazu asptrakovati tabelu po tabelu, ili query po query, nego treba apstrakcija da bude zasnovana na prirodi entiteta sa kojim radis, tipa imas recimo klasu User i sve sa njom radis, a ne zanima te da li userove podatke cuvas u jednoj ili 5 tabela, to je pitanje implementacije same klase i zavisi, izmedju ostalog i od tipa baze...

Otkrio je toplu vodu. To su ORM alati (koje smo već pomenuli i malo pojasnili) i da, polazi se sa druge strane. Nisam siguran da to treba bilo kome ko pravi klasičan (manji) sajt. Tamo gde je veće i kompleksnije, tamo PHP niko ne koristi..

degojs
05. 02. 2006., 16:51
zextra
A to sto programer koji koristi pgsql verovatno nikad nece hteti da koristi recimo sqlite... Pa, bitno je da ima i tu mogucnost...


Zavisi o cemu je rec.

Uzmi bilo koji veci sistem i jednostavno je uvek slucaj da imas vise baza sa kojima moras da radis, jer su pre npr. 10 godina stavili jednu bazu, pa su pre 5 kupili drugu, pa trecu.. I ne, nisu bili pametni da kupe uvek bazu istog proizvodjaca, iz mnogih razloga.

Znas li kolika je usteda u vremenu kad ne moras da se bakces u svom kodu sa svakom od tih baza posebno? I plus, kod je konzistentan, sto je jako lepo za odrzavanje.

A ako apsolutno nemas potrebu za tim, onda ne treba ni da gledas ove alate. Kao i uvek - ne guraj nesto gde ti ne treba, a kad ti zatreba - znaces sam vrlo dobro.

ivanhoe
05. 02. 2006., 20:59
Tamo gde je veće i kompleksnije, tamo PHP niko ne koristi..

uf, sad ga malo pretera...

bluesman
05. 02. 2006., 21:44
Veće i kompleksnije? :) To je tema sada za drugu raspravu :)

Ilija Studen
05. 02. 2006., 21:47
Da, ovu (http://www.devprotalk.com/showthread.php?t=436) ako su web aplikacije u pitanju (na DTP uglavnom jesu).

zextra
05. 02. 2006., 21:48
Uzmi bilo koji veci sistem i jednostavno je uvek slucaj da imas vise baza sa kojima moras da radis, jer su pre npr. 10 godina stavili jednu bazu, pa su pre 5 kupili drugu, pa trecu.. I ne, nisu bili pametni da kupe uvek bazu istog proizvodjaca, iz mnogih razloga.

U pravu si, ali _verujem_ da se to toliko "cesto" desava da ces opet imati par mogucih resenja datog problema... Jedno od njih ce sigurno biti i upotreba abstraction layera.

Nego, zasto uporno branis stav korporacijskih okruzenja gde je kompleksnost svakodnevna stvar? Jasno je da postoje slucajevi kada ovakvi alati sijaju punim sjajem, ali sam nekako stekao utisak da se ovde uglavnom prica o nekim malo-do-srednje kompleksnim problemima i projektima. Nemoj shvatiti ovo kao napad ili uvredu, samo te pitam zasto stalno branis taj stav.

degojs
05. 02. 2006., 21:53
Pa ne, naprotiv, lepo sam napisao:

A ako apsolutno nemas potrebu za tim, onda ne treba ni da gledas ove alate. Kao i uvek - ne guraj nesto gde ti ne treba, a kad ti zatreba - znaces sam vrlo dobro.

A zasto branim taj stav?

Nemoj shvatiti ovo kao napad ili uvredu, samo te pitam zasto stalno branis taj stav.

Zato sto ih ima koji provlace pricu tipa "kome to treba" samo zato sto njima nije zatrebalo. A ako im zatreba, sami ce da potraze to isto.. itd. Tako se valjda i doslo do tih alata, sto je neko rekao, majku mu, moze li ovo nekako lakse? :O