Database Abstraction Layer je komponenta, která zpomalí aplikaci, zvýší její hardwarové nároky a zkomplikuje programátorům přístup k databázi. To vše výměnou za iluzi, že by aplikace mohla fungovat i pod jiným databázovým strojem, než pro který byla původně vyvíjena.
Toliko definice DAL (na Wikipedii mají jinší). A teď několik praktických ukázek.
ADOdb
Nejslavnější PéHáPéčková DAL si říká ADOdb. Po přilinkování cca 400kB kódu k vaší aplikaci můžete dát sbohem nudným SQL příkazům, jako je
UPDATE `table` SET lastname='Jones'
WHERE lastname LIKE 'Sm%'
a nahradit je vzrušujícím zápisem
$record["lastname"] = "Jones";
$conn->AutoExecute(
$conn->nameQuote.'table'.$conn->nameQuote,
$record, 'UPDATE', "lastname LIKE 'Sm%'");
To není má zběsilá fantazie, to cituji jeden svěží příklad z dokumentace. Zvládnout ADOdb tedy není nic složitého, stačí se jen naučit novou syntaxi a odměnou bude tento přehledný zápis, kde snad ani nelze udělat chybičku. Pravda, zjištění, že uvedené hned z několika důvodů nebude fungovat třeba v MSSQL, nás dvakrát nepotěší, ale hlavně že je mír.
PEAR DB
Tak teď jsem trošku na rozpacích – není náhodou tou nejslavnější DAL pro PHP právě tato?
PEAR DB je od své kolegyně o poznání štíhlejší (140kB), nicméně pro svůj chod vyžaduje ještě knihovnu PEAR. Čím nás za svou přízeň odmění? Především šikovným zapouzdřením (nemyšleno ironicky, protentokrát ne) všech důležitých funkcí pro práci s databází a několika užitečnými drobnostmi navíc.
Zajímavé je například vkládání parametrů do SQL příkazů:
$db->query('INSERT INTO numbers
VALUES (?, ?, ?)', array(1, 'one', 'en'));
Leč při větším počtu parametrů je tato technika spíše kontraproduktivní. Shrnuto podtrženo: PEAR DB je zvládnutá rutina bez geniálních nápadů.
PDO
Dámy a pánové, o své místo na slunci se uchází novinka jménem PDO, nedílná součást PHP od verze 5.1. Funkčně se velice podobá PEAR DB, avšak obejde se bez linkování stovek kilobajtů (pomalého) kódu. Ale ptám se, je důvod k jásotu?
- zajistí alespoň základní přenositelnost mezi databázovými stroji?
- zjednoduší programátorům zápis SQL příkazů?
Obávám se, že nikoliv. Nebo snad znáte způsob, kterak snadno zapsat SQL příkaz, jenž by se pro MySQL resp. MS Access reprodukoval takto:
INSERT INTO `table` (`date`, `text`) VALUES ('2000-12-02', 'say: \'hello\'');
INSERT INTO [table] ([date], [text]) VALUES (#12/2/2000#, 'say: ''hello''');
Komentáře
Tom #1
Ja bych rekl, ze zlo si nerika Database Abstraction Layer, ale PHP. Presne to, co potrebujes/chces je pro javu a jmenuje se to Hibernate (www.hibernate.org).
Osobne jsem po nekolika velmi vyraznych zmenach v PHP, ktere zpusobily ze cele aplikace prestaly po upgradu najednou fungovat, velice zanevrel, protoze PHP (podle me) dela banda rozjivenych chuliganu…
Tom
migon #2
tak pod tohle bych se podespal a tak tak cinim 🙂
Zdeněk Merta #3
Souhlasím se vším, co bylo řečeno o zmiňovaných db abstrakčních layerech, nicméně bych je úplně nezatracoval. Používam Creole https://web.archive.org/…org:80/wiki/ a to na tom podle mě není zas až tak špatně
Vašek #4
Každý DBA je lepší, než přilinkovávat zběsilé includy s mysql_open() or die a pak dělat
mysql_select('SELECT a FROM tb WHERE c = "'.addslashes($c).'"');
Udělal jsem si vlastní DBA a to má pro mě hlavní výhodu, že umožňuje psát kratší a jednotnější, tudíž přehlednější aplikační kód.
Ironie nad novou syntaxí? Ehm, Texy?
Vašek #5
samozřejmě
mysql_query
místomysql_select
.Aspoň je vidět, že už to dlouho nepoužívám 🙂
Llaik #6
Souhlas, i kdyz budu asi mnohymi ukamenovan :)
jde o to, ze kdyz vyvijim aplikace, tak v dobe navrhu se rozmyslim, jaky db system pouzit – a pak samozrejme vyuziji jeho charakteristicke rysy k co nejvyssimu vykonu a stabilite.
Takze mi ta predstava, ze mam aplikaci napsanou pro postresql a prehozenim jednoho include mi bude fungovat s mysql, sqlite ci oraclem, mi prijde docela dost smesna :)
for i in
find . -name "*php"
; do cat $i | sed „s/mysql_/sqlite_/“ > $i.new; mv $i.new $i; done # ehm :)Llaik #7
#4 Vašku, ano, mam funkci pro query, ktera se stara o osetreni chyb a logovani. Ale pro jednu konkretni db.
Nelze napsat layer, ktery by mohl zmenou jedne konstanty prehodit pouzivany db system. Resp. zajistil stejnou funkcnost aplikace na jinem db systemu.
Takze mit funkce, ktere obali db volani nejakou dalsi funkcnosti samozrejme ano. Ale vytvorit stejne rozhrani pro vsechny db systemy s tim, ze aplikaci je jedno, ktere pouzije? Nepravdepodobne.
Jakub Vrána #8
PDO není Database Abstraction Layer, je to Data-access Abstraction Layer. První jmenovaná se snaží poskytnout jednotné rozhraní pro přístup k různým databázím a je jí zcela ADOdb a některé prvky v PEAR DB. Druhá jmenovaná se naopak o nic podobného nesnaží, rozdíly mezi databázemi se nesnaží maskovat a je lepší ji chápat pouze jako náhradu za všechna ta
*_query()
,*_fetch_*()
a další funkce jednotlivých databázových rozšíření.Database Abstraction Layer také nemám rád, rozdíly mezi jednotlivými databázemi jsou příliš zkrátka velké a psát rozhraní pro všechny mi přijde skoro totéž jako psát aplikaci tak, aby fungovala jak v PHP, tak v ASP… PDO naopak považuji za krok správným směrem mimo jiné i proto, že si na nic nehraje.
Jakub Vrána #9
#6 Llaiku, Já u svých aplikací volím stejný přístup – vyberu programovací jazyk a databázi a toho se držím. Potřeba databázové abstrakce nastává u projektů určených k širokému nasazení (např. open-source blogovací systém), kde chci získat co nejvíce zákazníků a nechci je omezovat výběrem databáze, protože někde tu možnost zkrátka nemají.
martinpav #10
Tu by som az tak uplne nesuhlasil. 400/140 (+PEAR Error a co ja viem co este :) ) KB je naozaj trochu vela ale :
Inak nepouzivam ani jeden z uvedenych hore. Prisli mi zbytocne velke a tazkopadne.
Co som este nasiel a vyzera zaujimavo je
https://web.archive.org/…org:80/trac/ (nemam skusenost takze tazko hodnotit pouzitelnost/rychlost)
#4 Vašku,
addslashes ?
Dufam ze v reali je pouzita mysql_real_escape_string :).
spaze #11
#6 Llaiku,
ty videl TJSN pri praci ? ;P
migon #12
Nejlepši je napsat si na každý projekt něco vlastního, podle potřeb projektu a pak případně jen změnit (napsat) ten jeden class pro jinou DB, jen se ponechaji stejné názvy metod.
llook #13
Další je ADOdb Lite, to vytvořili uživatelé, kterým ADOdb připadalo velký a pomalý.
Doteď jsem používal ADOdb, taky kvůli věcem jako MetaColumns a MetaType (to ADOdb Lite nemá). Věci jako autoExecute jsem si řešil po svém, ty adoácký jsou příšerný (hlavně mi vadí strtoupper(identifikátory)).
Od podobného nástroje vyžaduju jen pár věcí:
show fields from
nebopragma table_info()
). Metadata v nějaké jednotné formě, aby mi to třeba netvrdilo, žetext
je něco jiného nežclob
.#1 Tome, Já myslel, že Hibernate je ORM framework, nebo ne? Těch je pro PHP taky pár (http://wiki.cc/php/PHP_ORM), i když nic moc.
David Grudl #14
Můžu se zeptat, k čemu se v praxi hodí zjišťování informací o tabulkách, sloupcích apod.? Tedy pokuid nepíšu „phpXXAdmin“.
Budu rád, pokud sem napíšete, co vám na vašem DAL (či Data-access AL) nejvíce vyhovuje a co často používáte. Nebo naopak nevyhovuje.
halogan #15
#14 Davide Grudle, Research pro dalsi vyvoj Nette, ktere bude zitra predstaveno? (Jen odhaduji)
David Grudl #16
#15 halogane, hehe 🙂 Ale Nette to nebude, to si nechávám na jindy. Nicméně pokud máte tip na pěkný název evokující databáze, sem s ním!
tark #17
Já jsem si udělal jednoduchoučkej layer na cca 5–6kB a práci s db mi o hodně zjednodušil … Třeba:
nebo třeba když chci získat jen jeden řádek (přihlášení uživatele, vytažení jednoho konkrétního článku..), tak píšu
A to je spousta takových drobností. Navíc … když píšeš jednodušší projekt, tak je celkem jedno, jestli na to použiješ MySQL/SQlite/PgSQL/Oracle, protože příkazy
select a,b,c,d from table where a=1 and b=2 limit 5
zvládne snad každá db :)llook #18
#14 Davide Grudle, Pokouším se o vlastní ORM ve stylu Active Record z RoR. V nejjednodušším případě zadám jen název tabulky – sloupce a jejich typy se zadají sami:
Při produkčním nasazení by se to předgenerovalo, ale při vývoji se mi zdá lepší, když se struktura načítá při každém požadavku. Při každé změně upravovat dvě místa (databázi a třídu) je otravný.
K použitelnosti to má ještě daleko, narážím na hranice možností PHP4. Hlavně různé divné chyby při přetěžování metod a vlastností. Asi se s PHP4 brzy rozloučím…
llook #19
#17 tarku, Tak zrovna limit se u různých databází dělá různě. viz https://web.archive.org/…able_sql.htm
Další problém jsou quoted identifiers – skoro všude se používají dvojité uvozovky, ale MySQL používá zpětné apostrofy. Sice je možnost nepoužívat nic, ale pak si člověk musí dávat pozor na kolize s klíčovými slovy.
Janči #20
Chcel by som sa opýtať aký máte názor na DAO (data access objects)? Považujete to taktiež za hlúposť alebo myslíte že je to vhodne využiteľné?
tark #21
#19 llooku, tak pozor … ;) ja bezne pouzivam tohle a na mysql mi to funguje (jak 4.0, tak 4.1)
David Grudl #22
#21 tarku, llook měl na mysli závorky kolem identifikátorů, tedy názvů tabulek, sloupců a podobně. Třeba tvůj předchozí příklad by bez nich nefungoval, nelze psát
select a,b,c,d from table
ale select a,b,c,d from`
table`
tark #23
aha … 🙂 dík za vysvětlení, nejsem tak zdatnej „databázista“
mIREK #24
No nevím jestli je PEAR DB lepší než ADODB. Myslím si přesný opak, jelikož PEAR DB je závislý na PEAR. Nenabízí nic moc navíc narozdíl od ADODB.
Oněch 400kb je taky zavádějích, jelikož to obsahuje už i moduly, které se standartně nenačítají, ale pokud chcete, můžete je používat, jako je podpora do php5, podpora generování html prvků, které použije jen někdo…
Vkládání parametrů do SQL příkazů jak jsi uvedl u PEAR DB má ADODB taky a úplně stejně, tak nevím proč to u ADODB neuvedeš také, ale uvádíš tam UPDATE, kterej stejně skoro nikdo nepoužije…
Připadá mi, že seš vůči ADODB pěkně předpojatej 🙂 Co třeba benchmarky rychlosti? https://web.archive.org/…/lens/adodb/
Přitom si myslím, že zas tak špatné na nějaké ne db složité projekty to je špatné… Fuknce jako SelectLimit(), GenID(), InsertId() fungují na databázových serverech, které je podporují ale SQL syntaxi má každý jinou…
Stalo se mi že jsem na jednom projektu přistupoval k několika 2, ale jednou i 3 různým databázovým serverům, což zde třeba ADODB se mi celkem osvědčilo…
Já bych DB Abstraction Layers zase úplně nezatracoval, něco v nich je správně, problémem bývá, že krom klasických funkcí a funkcí, které se snaží řešit nekompatibilitu, jsou tam i funkce, které neřeší nic, jsou tam protože je dotyčný autor asi někdy potřeboval a narval je tam, ale už je nikdo nevyřadil…
Sám jsem je použil na pár věcech, které pěkně běhají jak na pgsql taky i mysql a s menšími úpravami i na firebirdu…
johno #25
DGX: Odpoved znie https://pear.php.net/…oexecute.php
mr #26
Lidi já nemůžu z toho, že ani pomalu nevím o čem se bavíte… 😉
llook #27
Tak kde to vázne?
Tento článek byl uzavřen. Už není možné k němu přidávat komentáře.