Na navigaci | Klávesové zkratky

Zlo si říká Database Abstraction Layer

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?

  1. zajistí alespoň základní přenositelnost mezi databázovými stroji?
  2. 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''');

Pokračování včetně jednoho řešení!

před 19 lety v rubrice PHP | blog píše David Grudl | nahoru

Mohlo by vás zajímat

Komentáře

  1. 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

    před 19 lety | reagoval [13] llook
  2. migon #2

    avatar

    tak pod tohle bych se podespal a tak tak cinim 🙂

    před 19 lety
  3. Zdeněk Merta #3

    avatar

    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ě

    před 19 lety
  4. 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?

    před 19 lety | reagoval [7] Llaik [10] martinpav
  5. Vašek #5

    samozřejmě mysql_query místo mysql_select.
    Aspoň je vidět, že už to dlouho nepoužívám 🙂

    před 19 lety
  6. 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 :)

    před 19 lety | reagoval [9] Jakub Vrána [11] spaze
  7. 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.

    před 19 lety
  8. 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.

    před 19 lety
  9. 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í.

    před 19 lety
  10. martinpav #10

    avatar

    Tu by som az tak uplne nesuhlasil. 400/140 (+PEAR Error a co ja viem co este :) ) KB je naozaj trochu vela ale :

    • kod sa neincluduje kompletne cely (Factory pattern)
    • pri pouziti encoderu problem s opatovnym spracovanim kodu odpada
    • vacsinou nieje nutna velka uprava kodu pri zmene php :)

    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 :).

    před 19 lety
  11. spaze #11

    #6 Llaiku,

    for i in find . -name „*php“; do cat $i | sed „s/mysql_/sqlite_/“ > $i.new; mv $i.new $i; done # ehm :)

    ty videl TJSN pri praci ? ;P

    před 19 lety
  12. migon #12

    avatar

    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.

    před 19 lety
  13. llook #13

    avatar

    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í:

    • Podporu pro mysql, mysqli a sqlite.
    • Zhruba to co dělá PDO.
    • Jednotné získávání metadat (abych se nemusel starat, jestli to je show fields from nebo pragma table_info()). Metadata v nějaké jednotné formě, aby mi to třeba netvrdilo, že text je něco jiného než clob.
    • Funkce pro formátování (escapování řetězců, formátování datumů apod.) hodnot i identifikátorů.

    #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.

    před 19 lety
  14. David Grudl #14

    avatar

    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.

    před 19 lety | reagoval [15] halogan [18] llook
  15. halogan #15

    #14 Davide Grudle, Research pro dalsi vyvoj Nette, ktere bude zitra predstaveno? (Jen odhaduji)

    před 19 lety | reagoval [16] David Grudl
  16. David Grudl #16

    avatar

    #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!

    před 19 lety
  17. 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:

    $link = mysql_connect($host,$user,$pass) or Die('Database error!');
    mysql_select_db($db,$link) or Die('Database error!');
    
    // vs
    
    $db->new &db($dbtype,$dbhost,$dbuser,$dbpass,$dbprefix,$debug);

    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

    $row = $db->getrow('select column1,column2,column3 from table');
    
    echo $row->column1 . $row->column 2 . $row->column3;

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

    před 19 lety | reagoval [19] llook
  18. llook #18

    avatar

    #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:

    class Person extends Record {
        var $_table = 'persons';
    }
    $person = &new Person;
    $person->setName('Vašek');
    $person->setCreated(time());
    $person->save();

    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…

    před 19 lety
  19. llook #19

    avatar

    #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.

    před 19 lety | reagoval [21] tark
  20. 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é?

    před 19 lety
  21. tark #21

    #19 llooku, tak pozor … ;) ja bezne pouzivam tohle a na mysql mi to funguje (jak 4.0, tak 4.1)

    $db->query('insert into abc (column1,column2,column3) values ("'.$column1.'","'.$column2.'","'.$column3.'")');
    před 19 lety | reagoval [22] David Grudl
  22. David Grudl #22

    avatar

    #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`

    před 19 lety
  23. tark #23

    aha … 🙂 dík za vysvětlení, nejsem tak zdatnej „databázista“

    před 19 lety
  24. mIREK #24

    avatar

    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…

    před 19 lety
  25. johno #25

    avatar
    před 19 lety
  26. mr #26

    Lidi já nemůžu z toho, že ani pomalu nevím o čem se bavíte… 😉

    před 19 lety
  27. llook #27

    avatar

    Pokračování zítra, včetně jednoho řešení!

    Tak kde to vázne?

    před 19 lety

Tento článek byl uzavřen. Už není možné k němu přidávat komentáře.


phpFashion © 2004, 2024 David Grudl | o blogu

Ukázky zdrojových kódů smíte používat s uvedením autora a URL tohoto webu bez dalších omezení.