Adatbázis absztrakciós rétegek PHP-hez II. (összehasonlítás)
Előző Adatbázis absztrakciós rétegek PHP-hez cikk kommentjei hatására, elvetettük azt az ötletet, hogy e folytatásban példákat hozzunk fel a rétegek felhasználásának módjára. Erre majd a harmadik részben fog sor kerülni. Amivel viszont folytatjuk, az egy összehasonlítás a PEAR:DB, PEAR:MDB2, ADOdb, és PDO rétegekről. Kiindulásképpen meg kell jegyeznem hogy a PDO, ami már az 5-ös PHP-val együtt érkezik, nem valósít meg adatbázis absztrakciós réteget, csak adathozzáférési réteget, eltekintve néhány funkciótól, mint például a tranzakciók kezelése.
Összehasonlító táblázat
A következő táblázatban összefoglaltam néhány érdekesebb, fontosabb funkciót, a teljesség igénye nélkül. Kérésre a táblázatot tovább bővíthetem, ezt jelezzétek a hozzászólások között. Remélem hogy az összehasonlítás segítségével, könnyebbé lehet tenni a választást az egyes rétegek között, az adott feladat elvárásainak megfelelően. A táblázatban X jelenti azt, hogy az adott réteg megvalósítja az absztrakciót az adott funkciónál. Ettől függetlenül, az adott funkciók használhatóak, közvetlenül az adatbázissal szemben, hiszen mindegyik rétegen keresztül lehet bármilyen SQL lekérdezést küldeni. Hordozhatóság szempontjából azonban ez a megoldás nem előnyös.
| DB | MDB2 | ADOdb | PDO | |
| Prepare támogatás | X | X | X | X |
| Bementi változók támogatása | X | X | X | X |
| Kimeneti változók támogatása (tárolt eljárások) | - | X | X | X |
| Tranzakció támogatás | X | X | X | X |
| LOB (Large Object) támogatás | - | X | X | X |
| LIMIT támogatás | X | X | X | - |
| Adattípusok kezelése | - | X | X | X |
| Teljesítmény monitorozás | - | - | X | - |
| ORM lehetőség | DB_DataObject | DB_DataObject | X | - |
| Gyorsítótár a lekérdezések eredményeire | - | - | X | - |
| Adatbázis sémák kezelése | - | MDB2_Schema (béta) | X | - |
Prepare és Bemeneti változók támogatása
Bemeneti változókat mind a négy réteg támogatja, azonban a változók összekötését (bind), a PEAR:DB nem. Prepare funkció mind a négy rétegben elérhető, tehát támogatott a lekérdezések, vagy adatmódosító utasítások hatékony, többszörös végrehajtása. A módszer segítségével, adatbázis szervertől függően akár 20-40% -os sebességnövekedés is elérhető.
Kimeneti változók támogatása
Tárolt eljárásoknál, az eljárás paraméterei lehetnek be illetve kimenő paraméterek. PEAR:DB egyáltalán nem támogatja a kimeneti paramétereket, emiatt azok használatánál teljesen az adatbázis szerver lehetőségeire kell hagyatkozni. MDB2, ADOdb, PDO-k támogatják a változók összekötését (bind), ezért ha egy tárolt eljárás paraméterét kötjük össze egy PHP változóval, a tárolt eljárás kimenő paraméterében megadott értéket a PHP változóban kell viszont látnunk. A funkciót személy szerint nem teszteltem MDB2 és PDO alatt. PDO honlapján az egyik hozzászólásban írják, hogy a kimeneti paraméterek sok esetben nem működnek rendeltetés szerűen. Ezt jelenleg nem tudtam kipróbálni, ha ki fogom, akkor módosítom a cikket.
Tranzakció támogatás
Trancakciók absztrakciós támogatása mind a 4 rétegben megoldott valamilyen szinten. A PEAR:DB és a PDO által megvalósított funkciók a legszegényebbek. PEAR:DB, MDB2, és PDOnál a tranzakciót egy try {…} catch() {…} blokkba rakva elkerülhető, hogy minden egyes utasítás utásnál vizsgálni kelljen, hogy az utasítás hiba nélkül futtot-e le. Természetesen a PEAR osztályoknál a hibakezelést megfelelően kell beállítani, amit a SetErrorHandling(PEAR_ERROR_EXCEPTION); paranccsal tehetünk meg. Az ADOdb kicsit más megoldást nyújt az egyszerűségre, mégpedig azt, hogy nem csak a commit és rollback funkciókat valósítja meg, hanem a StartTrans() és CompleteTrans() függvényeket is. (bővebben: Smart transactions) Ezzel a megoldással az absztrakciós réteg dönti el, hogy a tranzakció sikeres-e vagy nem, és ennek megfelelően fogadja el vagy utasítja el a tranzakció egészét.
LOB támogatás
LOB (Large object), vagyis nagy objektum támogatással a PEAR:DB-n kívül mindegyik réteg megbírkózik. Az, hogy mi számít nagy objektumnak adatbázis kezelő szoftvere válogatja. Gyakorlatilag a nagy objektum egy adattípus, ami a tábla mezőire jellemző. Az adatbázis absztrakciós rétegeken keresztül ezt, mint állománykezelőt tudjuk használni, például az fpassthru(), fread stb. függvényekkel. Megjegyzem, hogy az ADOdb-vel nem lehetséges a LOB mezőket állománykezelőként használni. ADOdb-t használva a LOB mező tartalmát egy PHP változóban kell átadni az UpdateBlob() függvénynek, vagy fájlok beillesztésére, az UpdateBlobFile() függvényt kell használni. Azok az adatbázis szerverek vagy driverek, ami LOB mezőt külön, nem az SQL utasításban kezelik (ADOdb forráskódja alapján): iBase, Informix, Oracle, ODBTP, PostgreSQL, SQL Anywhere. MSSQL esetében csak bin2hex átalakítás történik bináris lob-nál (BLOB), és a kapott adat ugyanúgy az SQL utasításba kerül.
LIMIT támogatás
Limit funkció megvalósítása PDO-n kívül mindegyik régetben megtalálható. Például PDO-n keresztül SELECT * FROM table LIMIT 10; utasítás elküldhető és az eredményhalmaz 10 rekordot fog tartalmazni, de az Oracle nem támogatja a LIMIT parancsot. Helyette a következő megoldás használható (LIMIT $from, $count esetén): SELECT id, name FROM (SELECT rownum as linenum, id, name FROM table WHERE rownum <= $from+$count) WHERE linenum >= $from+1; Azoknál az absztrakciós rétegeknél amelyek támogatják a LIMIT emulálását, nagyon egyszerűen megoldható a hordozhatóság ilyen esetekben is. Például MDB2-nél a SetLimit() függvény használatával, amit az adott adatbázis driver megfelelően implementál.
Adattípusok kezelése
Leginkább beszúrásnál vagy adatmódosításnál vehetjük igénybe az adatbázis absztrakciós rétegek e szolgáltatását. Adattípusokat a PEAR:MDB2, ADOdb és a PDO kezeli a fenti négy réteg közül. Lényege, hogy bemenő paraméterenként megmondhatjuk, hogy azok milyen típusúak (szám, karakterlán, dátum, időbélyeg, stb.). Ezzel a módszerrel elkerülhető, hogy megfelelő formátumra kelljen alakítanunk például a dátumokat. Természetesen az átalakítás az adott adatbázis kezelőtől függ, és azt, a rétegben használt meghajtó végzi.
Teljesítmény monitorozás
A teljesítmény monitorozás egyik, az ADOdb által támogatott szolgáltatás, ami csak néhány elterjedt adatbázis kezelő rendszerről nyújt információt, ezek: MySQL, PostgreSQL, Oracle, MSSQL, Informic és DB2. Segítségével részletesebb információt nyerhetünk a szerver “egészségi állapotáról”, mint például a PHPMyAdmin-ba beépített futási információk lekérdezésének lehetősége. Ilyen többletszolgáltatás például a processzor terheltség, a lassú lekérdezések listázása. A szolgáltatásról további információ a következő oldalon található: http://phplens.com/lens/adodb/docs-perf.htm
Object Relation Mapping
A cikk első részében is említett DB_DataObject segítségével az ORM funkciók megvalósíthatók PEAR:DB és PEAR:MDB2 -re alapozva is. E két rétegen kívül az ADOdb nyújt ilyen szolgáltatást. Gyakorlatilag arról van szó, hogy egy objektumot megfeleltetünk egy adatbázis táblának, implementálhatjuk az objektumra jellemző egyéb funkciókat, például: tegyük fel, hogy adott egy tábla amiben felhasználókat tárolunk. Ennek a táblának megfeleltetünk egy objektumot, és az alap funkciókon kívül (egy felhasználó lekérdezése, adatainak módosítása, stb) implementálhatunk ugyanebbe az osztályba például “ismerősök lekérdezése” funkciót, stb. Talán sejthető, hogy mennyire tág lehetőségeket nyújt ez a funkció. Ezen kívül az SQL utasítások (insert, update, select) nagy részét a megfeleltetett objektum automatikusan generálja. Ezzel elérhető, hogy az objektum bővítésével nem jár az SQL utasítások változtatása. Ugyanakkor az alkalmazásban szereplő egységek (unitok), és a hozzájuk kapcsolódó funkciók könnyen szeparálhatóak egymástól. Szerintem az ORM használatával sokat egyszerűsödhet az alkalmazás logikájának felépítése.
Gyorsítótárazás a lekérdezések eredményeire
A lekérdezések eredményének gyorsítótárazását, a fenti négy réteg közül csak az ADOdb nyújtja számunkra. A gyorsítótárban elhelyezett eredmények nem csak a weboldal generálásának idejéig élnek, hanem az általunk megadott ideig. Ezzel a módszerrel nagyon könnyen megoldható, például egy főoldal, vagy az oldal egyes, ritkán változó részeinek gyorsabb működése. Azok a lekérdezések amelyek eredménye a gyorsítótárban megtalálható, nem jutnak el az adatbázis kezelő szerverhez, hanem az adatbázis absztrakciós réteg a gyorsítótárból veszi elő, a megfelelő eredményt.
Adatbázis sémák kezelése
Adatbázis sémák gyakorlatilag leírások, definíciók az adatbázisban szereplő táblákról, azok mezőiről, indexeiről. Sémákat, az ADOdb megfelelően támogatja. A PEAR:MDB2-re alapozva, a PEAR:MDB2_Schema csomag is támogatja a szolgáltatást, azonban ez még béta verzióban jár. Sémák kezelésével elérhető, hogy az absztrakciós rétegen keresztül definiáljuk az adatbázist leíró paramétereke, pl.: adatbázisok paramétereit, táblákat, azok mezőit, stb. Ezeket az adatokat definiálva lehetőség nyílik, SQL parancs írása nélkül adatbázist és táblát létrehozni, módosítani. Ennek segítségével az alkalmazásunk adatbázis kezelő rendszerek közötti hordozhatóságát növelhetjük. ADOdb adatbázis séma szolgáltatásaival kapcsolatban a következő oldal nyújthat több információt: http://phplens.com/lens/adodb/docs-datadict.htm
Összegzés
Pro és kontra mindegyik réteg mellett van. Talán a PEAR:DB-t nem tudnám előnyben részesíteni a többivel szemben. PEAR:MDB2 funkciókban a második leggazdagabb, szerintem nem lehet rossz választás, ha ezekre szükségünk is van. Ha nem tervezzük, hogy az alkalmazásunk más adatbázis kezelőt fog használni a PDO, mint lehetőség is felmerül. Nem tartom rossz kezdeményezésnek, de személy szerint nem tartom elég megbízhatónak, és hibamentesnek. Idővel biztosan fog változni a véleményem, ahogy javítják a meglévő hibákat. Érett és sokkal stabilabb, valamint funkciókban jóval gazdagabb az ADOdb. Rossz oldala viszont, hogy C nyelvű PHP kiterjesztése nélkül sokkal lassabb mint például a PDO. Szerintem ha már ezek a sebességek számítanak, akkor nem kisebb alkalmazásról beszélünk, és talán saját szerveren fut, vagy fog futni. Emiatt ezt, nem tartom hatalmas hibának.


2 hozzászólás, szólj hozzá Te is!
Balázs
Kérdésem: a Zend Framework DB osztályai holl lehetnek ebben a sorban?
Amit a dokumentációjából néztem, olyanokat is tud, hogy pl MyISAM táblákat, SQL lite-ot relációsként kezelhet.
2009. 02. 17.
Hozzászólás írása: “Adatbázis absztrakciós rétegek PHP-hez II. (összehasonlítás)”