DevProTalk

DevProTalk (http://www.devprotalk.com/index.php)
-   SQL baze podataka - Sponzor: Baze-Podataka.net (http://www.devprotalk.com/forumdisplay.php?f=10)
-   -   DB Abstraction Layer, koji koristite ? (http://www.devprotalk.com/showthread.php?t=573)

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:
PHP kôd:

$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:
PHP kôd:

$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

Citat:

Originalno napisao Pedja
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 interfejsa moguće je napraviti da se objekat tretira kao niz, te da bude izvodljivo:

PHP kôd:

$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

Citat:

Originalno napisao ivanhoe
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

Citat:

Originalno napisao bluesman
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 ORM?
Primere modela možeš naći ovde, od kojih bih izdvojio many-to-many, rekurzivnu many-to-one relaciju na samoga sebe, i veoma fin primer implementacije category modela koji možeš koristiti u svojim aplikacijama.

A sam db-api će postati znatno lepši kada "magic-removal" 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

Citat:

Originalno napisao Ilija Studen
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

Citat:

Originalno napisao Pedja
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

Off Topic: 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 :)


Vreme je GMT +2. Trenutno vreme je 12:48.

Powered by vBulletin® Verzija 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Copyright © DevProTalk. All Rights Reserved.

Mišljenja, saveti, izjave, ponude ili druge informacije ili sadržaji nastali na Sajtu su vlasništvo onoga ko ih je kreirao, a ne DevProTalk.com, tako da ne morate da se oslanjate na njih.
Autori poruka su jedini odgovorni za ovakve sadržaje. DevProTalk.com ne garantuje tačnost, kompletnost ili upotrebnu vrednost informacija, stavova, saveta ili datih izjava. Ne postoje uslovi pod kojima bi mi bili odgovorni za štetu ili gubitak koji je posledica bilo čijeg oslanjanja na nepouzdane informacije, ili bilo kakve informacije nastale kroz komunikaciju između registrovanih članova.
Web sajt može sadržavati linkove na druge web sajtove na Internetu ili neke druge sadržaje. Ne kontrolišemo niti podržavamo te druge web sajtove, niti smo pregledali bilo kakve sadržaje na takvim sajtovima. Mi nećemo biti odgovorni za legalnost, tačnost ili prikladnost bilo kog sadržaja, oglasa, proizvoda, usluga ili informacije lociranim na ili distribuiranih kroz druge web sajtove, niti za bilo kakvu štetu nastalu kao posledica takvih informacija. DevProTalk.com drži i čuva druga prava vlasništva na web sajtu. Web sajt sadrže materijale zaštićene copyright-om, zaštitne znakove i druge informacije o pravu vlasništva ili softver. Članovi mogu poslatu informacije zaštićene pravima vlasništva njihovih nosilaca i ona ostaju zaštićena bez obzira da li su oni koji prenose te informacije to naveli ili ne. Osim informacija koje su u javnom vlasništvu ili za koje dobijete dozvolu, nemate pravo da kopirate, modifikujete ili na bilo koji način menjate, objavljujete, prenosite, distribuirate, izvršavate, prikazujete ili prodajte bilo koju informaciju zaštićenu pravima vlasništva. Slanjem informacija ili sadržaja na bilo koji deo DevProTalk.com, Vi automatski dozvoljavate i predstavljate garanciju da imate pravo da dozvolite DevProTalk.com ili članovima DevProTalk.com bespovratnu, kontinualnu, neograničenu, globalnu dozvolu da koriste, kopiraju, izvršavaju, prikazuju i distribuiraju takve informacije i sadržaje i da iz takvih sadžaja koriste bilo koji deo u bilo koje svrhe, kao i pravo i dozvolu da koriste gore navedene sadržaje. Svi zaštitni znakovi (trademarks), logotipi, oznake usluga, firme ili imena proizvoda koji se pominju na ovom web sajtu su vlasništvo kojim raspolažu njihovi vlasnici.