69 komentářů k článku Databáze v PHP elegantně s NotORM:

  1. Michal Kleiner

    statisíce záznamů

    Ahoj,

    knihovnu NotORM se zájmem sleduji a chystám se vyzkoušet. Rád bych se ale předem zeptal, jak se bude chovat v situacích, kdy by se do WHERE IN (…) podmínky měly dostat desítky tisíc ID z nadřazené tabulky.. nemá query string omezenou délku?

    Díky za případnou odpověď.

    MK

    1. Jakub VránaAutor příspěvku

      Re: statisíce záznamů

      Např. v MySQL je délka dotazu omezena konfigurační direktivou max_allowed_packet. Velké výsledky je ale stejně lepší zpracovávat postupně – nejen kvůli délce dotazu, ale i kvůli zabrané paměti. Typicky to je lepší i pro databázový server. Je to popsané na http://www.notorm.com/#faq.

      1. radik

        Re: statisíce záznamů

        Ja myslim ze tak ta otazka nebyla minena… Pokud ten prvni select vrati treba 1000 zaznamu (cemuz bych se mel rekneme vyhnout, ale muze se stat, ale to same plati i pro 100 redku, coz uz je bezne), tak abych mohl sestavit ten IN, tak musi knihovna projit vracene radky a posladat z nich IN. Pak tenhleten rekneme dlooooooouhy dotaz poslu do MySQL, ten to nejdriv musi parsovat a zase ty IDcka ze stringu lovit, pak to musi chudak nejak vykonat (nerad bych podcenoval jeho optimalizator, ale optimalni to jiste nebude) a pak to posle na server, kde se to musi znovu prochazet a joinovat ty vracene radky… Vubec radeji nemluvim o tom, jak je to v pripade, ze je tech joinu vic nebo se dela join pres dalsi tabulku.

        Nemuzu si pomoct, ale kdyz proti tomu postavim jeden rucne psany JOIN, na ktery je server optimalizovany, prijde mi to dost nesrovnatelne…

        1. Jakub VránaAutor příspěvku

          Re: statisíce záznamů

          Doporučuji si to prostě změřit. Parsování dotazu je prakticky okamžité, dotazy používající IN vyhodnocuje MySQL velmi efektivně (např. lépe než BETWEEN) a spojení dat v PHP (kterému nevhodně říkáte joinování) probíhá v konstantním čase, jak už jsem vysvětloval.

          1. radik

            Re: statisíce záznamů

            Zmeril jsem… Tvrdit o cemkoli, ze je „prakticky okamzite“ je podle me dost odvazne, ale budiz. Na realnych datech, kde se z tabulky s miliony radku vybira asi tisicovka a ta se joinuje s tabulkou s desetitisici radku mi to vyslo tak, ze jen provedeni dvou selectu (jeden s IN) trvalo 150–200% casu JOINu… coz podle me nemi na zatizenych webech zanedbatelne (nepocitam narust zateze na strane PHP, ktery bude prakticky zadny, ale presto nejaky). A joinovani je mozna nehodne slovo, ale pokud je join=spojit a „spojovani v PHP“ nahrazuje onen sql JOIN, a myslim, ze si jiste rozumime ;)

            1. tiso

              Re: statisíce záznamů

              Ty niekde potrebuješ VYPÍSAŤ asi 1000 záznamov z databázy? Môžeš uviesť konkrétny príklad?

              1. Jakub VránaAutor příspěvku

                Re: statisíce záznamů

                Poměrně běžné to je u XML exportů, např. pro Zboží nebo Sitemaps.

            2. Jakub VránaAutor příspěvku

              Re: statisíce záznamů

              Test by to chtělo udělat pořádněji, protože záleží na spoustě věcí. Např. „jen provedeni dvou selectu“ je jen část celého problému, protože data je potřeba taky přenést. Tím pádem taky záleží na tom, jestli jde o server lokální nebo vzdálený. Záleží taky na spojovaných tabulkách, jestli se jejich vztah blíží 1:1 nebo jde o 1:N, jde taky o šířku dat v jednotlivých tabulkách.

              Test prostě musí být přesný a reprodukovatelný, takhle to je jen výkřik do tmy stejně jako kdyby řekl, že na reálných datech je NotORM dvakrát rychlejší.

              Každopádně jak jsem ukazoval, tak NotORM nikdy nebude řádově horší (tedy u 1000 řádek třeba tisíckrát) než jiné řešení – nemůže ustřelit. Může být pouze konstanta-krát horší, což se ve velkých objemech řeší snadno. Naopak spojování tabulek ustřelit může v objemu přenášených dat, které má na celkovou rychlost taky vliv. Tam, kde NotORM přenese O(N + M) dat může spojování tabulek přenášet O(N * M) dat.

  2. Mastodont

    Ehm ..

    Všimněte si, že z tabulek se přenáší jen ty sloupce, které se nakonec použijí, aniž by se jejich seznam musel kdekoliv specifikovat. To je zařízeno tak, že knihovna napoprvé získá všechny sloupce, pak si ale zapamatuje, které sloupce skutečně použila a příště už si vyžádá jen ty použité.

    To je myšleno jako další level v podporování lenosti programátorů? :)

  3. okbob

    Pro jednoduché věci ano

    Ale pro větší data a projekty je to stejně nebezpečné jako klasické ORM. Navíc to vede k naivnímu způsobu programování, kdy bombarduji SQL databázi jednoduchými dotazy – což vyhovuje MySQL, ale všem ostatním databázím to dobře nedělá, přičemž je to stejně hloupost, protože ostatní db si dokáží poradit i s komplikova­nějšími než triviálními dotazy.

    1. Jakub VránaAutor příspěvku

      Re: Pro jednoduché věci ano

      Ono nejde jen o složitost dotazů, ale i o to, kolik se přenáší dat. Podívej se podrobně na obrázky v odkázaném článku http://php.vrana.cz/srovnani-dotazu-do-zavislych-tabulek.php. Spojování tabulek vede k tomu, že se opakovaně přenáší data, která už se jednou přenesla. To nevyhnutelně stojí nějaký čas. Naproti tomu NotORM klade konstantní počet dotazů, kde se přenáší objem dat minimální. V odkázaném článku je i srovnání časů – tam jsou výsledky vyrovnané.

      Zkus si udělat podobný test i pro PostgreSQL, možná budeš překvapen. Záleží samozřejmě na charakteru dotazů – spojování tabulek 1:1 se dá trochu efektivněji dělat i JOINem, ale jakmile chceš přenést hodně sloupců z jedné tabulky a k tomu připojit hodně řádků z jiné tabulky, tak objem přenesených dat zbytečně narůstá.

      1. okbob

        Re: Pro jednoduché věci ano

        Nebudu se přít, že o tom, že denormalizovaná data jsou větší – to je jasné. Na druhou stranu – pokud nejsou extrémně delší, tak je mnohem větší brzdou režie na straně serveru – každý dotaz se musí poslat po síti, musí se parsovat, musí se generovat plán, musí se generovat snapshot. Navíc obcházíš planner – v případě chtřejších db, lze efektivně provést JOIN aniž bys musel mít index na tabulkách – čímž zase zrychluji DML operace. Případně planner si může vybrat z několika metod implementace JOINu – v tvém případě je to vždy NESTED LOOP, což je ta nejpomalejší metoda – byť je v některých případech tou správnou.

        Minimálně jsou tvá doporučení hodně diskutabilní – pokud bych měl problém s pomalou sítí – pak bych spíš měl použít uloženou proceduru. Opět není problém přímo v uložené proceduře přeformátovat výsledek do JSON, XML, HTML formátu. Co se týče mne, tak rozhodně nedoporučuji tvůj přistup aplikovat pro PostgreSQL a netriviální projekty – pokud budu řešit menší eshop – nic se neděje. Při větších objemech, při komplexnějších operacích by to nedopadlo dobře – resp. výsledek by byl zbytečně zoufale pomalý.

        1. Jakub VránaAutor příspěvku

          Re: Pro jednoduché věci ano

          NESTED LOOP se přece vůbec neprovádí. Při něm se pro všechny řádky jedné tabulky prozkoumají všechny řádky druhé tabulky a řádky splňující podmínku se vrátí (časová složitost M * N). NotORM nic takového nedělá – jedním dotazem získá z jedné tabulky všechny řádky výsledku a druhým dotazem získá z druhé tabulky všechny připojené řádky. Spojí to pomocí haštabulky, tedy pro každý řádek v konstantním čase. Celkový čas maximálně M + N. Líp to nejde.

          Možná jsi měl na mysli případ, kdy je potřeba podle řádků v jedné tabulce vyfiltrovat řádky v druhé tabulce. To NotORM taky podpuruje, jak je popsáno v dokumentaci.

          // chci získat tagy všech aplikací autora 11
          $db->application_tag("application_id", $db->application("author_id", 11));

          Tento kód spustí následující dotaz, se kterým si databáze hravě poradí.

          SELECT ... FROM application_tag WHERE application_id IN (
            SELECT id FROM application WHERE author_id = 11
          )

          Formátování výsledku přímo v SQL je podle mě lepší se vyhnout. Tam prostě prezentační logika nepatří, od toho jsou šablony.

          Budu velmi rád, když mi ukážeš projekt, na kterém by si NotORM podle tebe vylámal zuby. Načrtni strukturu databáze, dodej ukázku dat a požadavky na získávaná data a já ti ukážu, jak se v NotORM dají tyto požadavky efektivně vyřešit.

          1. okbob

            Re: Pro jednoduché věci ano

            Myslím si, že stačí, když dojde k situaci, kdy ORM vygeneruje dotaz … IN (několik stovek id). Tam budeš zbytečně tlačit mezi serverem a klientem data, která vůbec nepotřebuješ. Ty to dokážeš obejít skrz nested metody – ok, kolik programátorů se k tomu dopracuje? Navíc kód, který to vygeneruje je minimálně pro MySQL menší než 5.5 neefektivní (v případě větších objemů).

            Můj primární protiargument je ten, že tvé NotORM dokáže v rukách průměrného programátora napachát stejnou škodu jako klasické ORM – stejně si musí výsledně programátor ověřovat dotazy, které tvoje knihovna vygeneruje, tudíž úspora práce je minimální a čitelnost celku horší. Z mého pohledu má knihovna NotORM stejné nevýhody jako klasické ORM – jen je menší – spíš bych ji pojmenoval SimpleORM.

            Formátování výsledku v SQL může mít svůj význam – a) tehdy kdy řeším výkon, b) kdy db požívá víc aplikací – a třeba PHP je pouze jedním z možných interface – samozřejmě – nesmí se to přehánět – je blbost generovat v SQL komplet html stránku.

            1. Jakub VránaAutor příspěvku

              Re: Pro jednoduché věci ano

              Několik stovek ID se bude zbytečně tlačit pouze u vazeb 1:1, které jsou u většiny aplikací ojedinělé. Naopak u vazeb 1:N a M:N dojde většinou k redukci objemu přenesených dat.

              Příklad vazby 1:N je $application->author["name"]. Když bych to vyřešil spojením tabulek, tak se stejné jméno autora (a případně další informace, které bych o něm chtěl) bude přenášet opakovaně u všech aplikací, které autor vytvořil. Celkově se přenese a * (s + id) dat, kde a je počet získávaných aplikací, s délka jména a id délka primárního klíče (předpokládám, že chci přenést i id autora, abych na něj mohl třeba vytvořit odkaz). NotORM přenese jméno autora (a případné další informace) jen jednou a opakovaně přenese pouze jeho ID. Celkový objem přenesených dat je tedy a * id + b * (s + 2*id), kde b je počet různých autorů ve výpisu. To je horší pouze v situaci, kdy počet různých autorů skoro dosahuje počtu vypisovaných aplikací (tedy téměř vazba 1:1).

              U vazeb M:N (např. $application->application_tag()) by bylo spojení tabulek úplný zabiják, protože pro každou nálepku by se znovu přenášely všechny informace o aplikaci. Lepší by to mohlo být pouze v případě, kdy by aplikace měly žádnou nebo jen jednu nálepku (tedy opět téměř vazba 1:1).

              Omezení záznamů z jedné tabulky podle dat v druhé tabulce se dělá v NotORM zcela přirozeně a mrzí mě, že jsem to do článku nenapsal. Že to vygeneruje poddotaz (ty asi říkáš nested metodu), je zcela transparentní. Můžeš prosím popsat, co by mělo být před MySQL 5.5 neefektivní? U poddotazů dokáže MySQL použít stejné indexy a další optimalizace jako u spojení tabulek.

              Vygenerované dotazy typicky kontrolovat potřeba není – jsou prostě jednoduché a rychlé. Opravdu bych byl rád za příklad, na který podle tebe NotORM nebude dost efektivní. Navíc i napsat kód tak, aby byl s NotORM neefektivní, dá na rozdíl od ručního psaní dost přemáhání.

              1. okbob

                Re: Pro jednoduché věci ano

                Lišíme se v názoru na to, co je horší – jestli objem přenesených dat nebo počet SQL dotazů – v tom se neshodneme. Řešit přenos po lokální síti mi přijde irelevantní (v běžných dimenzí .. do 100KB výsledku) – něco jiného je čtení/zápis na disk.

                Ohledně poddotazů – v materiálech k 5.5 (a k 5.4) jsou informace o tom, že poddotazy jsou znatelně rychlejší (v těchto verzích). Z toho vycházim.

                1. Jakub VránaAutor příspěvku

                  Re: Pro jednoduché věci ano

                  Rozhodně se shodneme v tom, že příliš velký počet dotazů je pro databázi smrt. Takže když kvůli jednomu výpisu položím celkem 1 + M + M * N dotazů (kde M je třeba počet aplikací a N počet jejich nálepek), tak to prostě bude pomalé. Ale jestli kvůli stejnému výpisu položím 1 dotaz (který přenáší hodně dat) nebo 3 dotazy (které přenáší málo dat), tak to bude velmi podobné. Asymptoticky se položí dotazů stejně. Naopak se může u spojení tabulek asymptoticky zhoršit objem přenesených dat. NotORM je prostě asymptoticky optimální a použitá konstanta může celkový výsledek buď trochu zhoršit nebo trochu zlepšit, nikdy ho ale nezhorší podstatně.

                  Zlepšení poddotazů bude nejspíš v něčem jiném. Jejich současné použití v NotORM je rychlé i ve starších verzích.

                  1. logik

                    Re: Pro jednoduché věci ano

                    Ne že bych měl něco proti tomudle frameworku, na spoustu věcí se velmi hodí, ale IMHO při složitějších aplikacích někdy selhat musí.

                    Vycházím z jednoduché premisy: Proč by databázové plannery byly tak sofistikované a často jim trvalo několik verzí (např. Mysql), než se podaří by generovaly alespoň trochu rozumné plány pro složitější dotazy, když by takovýto v podstatě triviální algoritmus vracel optimální nebo skoro optimální řešení?

                    1. Jakub VránaAutor příspěvku

                      Re: Pro jednoduché věci ano

                      Je to zajímavá úvaha. Vtip je v tom, že NotORM ulehčuje databázi práci – radí jí, v jakém pořadí má vyhodnocovat tabulky a jaké z nich bude potřebovat řádky. To je u obecného dotazu se spoustou spojených tabulek poměrně pracné.

                      Pro databázi nicméně pořád ještě nějaká práce zbývá – musí se rozhodnout, jaké u tabulek použije indexy a původní práce ji čeká i u poddotazů (které NotORM taky generuje, jak je popsáno v dokumentaci a jak jsem zmínil v diskusi).

                      Každopádně budu rád za úlohu, na které si NotORM podle vás vyláme zuby.

                      1. logik

                        Re: Pro jednoduché věci ano

                        No, pokud bych jako bernou minci bral projekt, na kterém pracuju teď, tak tam by si NotORM myslím zuby nevylámalo.
                        Ale z úplně jednoduchého důvodu – buďto používám jednoduché selecty,
                        kde je úplně jedno, co se použije, nebo vnořené poddotazy, kde IMHO notOrm takovou výhodu nemá (rychlost i srozumitelnost ručně napsaného dotazu je zhruba podobná zápisu v notorm) (ručně je samo nepíšu), nebo stored procedury, často obalující různé rekurzivní SQL dotazy, což by pomocí notORM nešlo asi vůbec?

                        Jinak v podstatě souhlasim, že u databáze, která vnořené dotazy umí správně optimalizovat (s čímž třeba mysql měla problémy – myslím ale, že větší problém byl u dotazů typu NOT IN – umí je notOrm?) tak správně napsané dotazy v notOrm by neměly bejt (moc :-)) špatné. „Problém“ spíš vidím v tom, že u složitějších projektů použiju různý kombinace poddotazů, rekurzivní poddotazy a podobný věci, a ty v notOrm zas tak hezky popř. vůbec napsat nepůjdou.

                        Takže to, že notOrm většinou (klidně si to změň na vždy) generuje dobrý plány imho neni tim, že by to byl „univerzálně použitelnej princip“, ale spíš že notOrm v základu velmi hezkým způsobem obaluje pouze část toho, co databáze umí. Pokud to člověku v projektu stačí, pak notOrm může bejt dobrá volba. Mě by to ale v projektech co píšu většinou nestačilo.
                        Pokud by se ale přepsalo tak, aby umělo i stored procedury, pak by to byl asi opravdu hezkej frontend pro aplikace, který maj většinu logiky v databázi.
                        Anebo naopak na aplikace, kde člověku stačí to, co notOrm pokrejvá hezky. Ale když ona je stromová struktura tak „přirozená“ a rekurzivní dotazy tak hezký :-)

                        1. Jakub VránaAutor příspěvku

                          Re: Pro jednoduché věci ano

                          Rekurzivní dotazy nepoužívám, lepší je podle mě přizpůsobit strukturu databáze a použít nejlépe Traverzování kolem stromu.

                          Dotazy NOT IN se dají pokládat neintuitivním zápisem where(„field_id NOT“, $db->$tableName()).

                          Podporu uložených procedur přidat neplánuji.

                            1. fos4

                              Re: Pro jednoduché věci ano

                              Jinak by mne zajimalo jak se resi nasledujici problem:
                              Jsou tri tabulky: produkty (id, nazev, kategorie_id), cenoveskupiny (id, nazev) a ceny (cenoveskupiny_id, produkt_id, cena).

                              Jak efektivne vybrat produkty z dane cenove skupiny (a nejake dalsi podminky jako kategorie apod.) s cenou od do a seradit od nejlevnejsiho.

                              1. danaketh

                                Re: Pro jednoduché věci ano

                                Pomocí VIEW :) Nezkoušel jsem výkon na MySQL ani PostgreSQL ale třeba na MSSQL mám odzkoušeno, že je rychlejší udělat pohled, než posílat několik dotazů a pak to šroubovat k sobě.

                                Databáze si sestaví nějaké schéma (zase tak moc do střev tomu nevidím) a pak už jsou selecty sranda, protože databáze ví kudy postupovat (za předpokladu, že existují indexy – bez nich se taky dá databáze úplně sestřelit) a dotazy tak trvají chviličku a je to menší zátěž pro server.

                              2. Jakub VránaAutor příspěvku

                                Re: Pro jednoduché věci ano

                                Hračka:

                                $skupina = 2;
                                $kategorie = 0;
                                $cena_od = 10;
                                $cena_do = 1000;
                                
                                $ceny = $db->cena()
                                    ->where("cena BETWEEN ? AND ?", $cena_od, $cena_do)
                                    ->where("cenovaskupina_id", $skupina)
                                    ->where("produkt_id", $db->produkt("kategorie_id", $kategorie))
                                    ->order("cena")
                                ;
                                
                                foreach ($ceny as $cena) {
                                    echo $cena->produkt["nazev"] . " ($cena[cena])n";
                                }

                                Položí se tyto dotazy:

                                SELECT produkt_id, cena
                                FROM cena
                                WHERE (cena BETWEEN ? AND ?)
                                AND (cenovaskupina_id = '2')
                                AND (produkt_id IN (SELECT id FROM produkt WHERE (kategorie_id = '0')))
                                ORDER BY cena;
                                
                                SELECT id, nazev FROM produkt WHERE (id IN ('1', '2'));
                                1. fos4

                                  Re: Pro jednoduché věci ano

                                  Díky, NotORM mně přijde dobrý na dotazy které jsou ± stejné a a podmínky v nich se moc nemění.
                                  Pokud by se v předchozím příkladu změnily podmínky a uživatel už by nechtěl filtrovat podle ceny ale jen podle kategorie tak už se musí změnit celý zápis, neboť programátor už musel sám určit z která tabulky se bude vybírat jako první.

                                  1. Jakub VránaAutor příspěvku

                                    Re: Pro jednoduché věci ano

                                    Nikoliv. Když by se nemělo filtrovat podle ceny, tak by kód zůstal úplně stejný, jen by zmizela podmínka „cena BETWEEN ? AND ?“. Pořád je totiž ještě potřeba omezit cenovou skupinu a podle ceny setřídit. Když by se podle ceny třídit nemuselo, tak by se kód přepsat mohl, ale nemusel.

                                    1. fos4

                                      Re: Pro jednoduché věci ano

                                      jde mně o to že uživatel většinou určuje podmínky a dle čeho seřadit a mysql v tomto ohledu většinou pomůže tím že správně vybere první tabulku.

                                      Vlastně ani moc nejde o NotORM ale jak vyřesit strukturu v mysql aby tyhle dotazy byly co nejvíce efektivní.

                              3. Jakub VránaAutor příspěvku

                                Re: Pro jednoduché věci ano

                                V aktuální verzi to je ještě jednodušší:

                                $ceny = $db->cena()
                                    ->where("cena BETWEEN ? AND ?", $cena_od, $cena_do)
                                    ->where("cenovaskupina_id", $skupina)
                                    ->where("produkt.kategorie_id", $kategorie))
                                    ->order("cena")
                                ;

                                Položí se tento dotaz:

                                SELECT cena.produkt_id, cena.cena
                                FROM cena
                                LEFT JOIN produkt AS produkt ON cena.produkt_id = produkt.id
                                WHERE (cena BETWEEN ? AND ?)
                                AND (cenovaskupina_id = '2')
                                AND (produkt.kategorie_id = '0')
                                ORDER BY cena;
                          1. logik

                            Re: Pro jednoduché věci ano

                            Ohejbat realitu (zachycenou DB) tomu, že chci použít nějakej nástroj je IMHO většinou cesta do pekel. Respektive na to člověk pak hrozně nadává, když je třeba provést v projektu změna. A ať je udělaná analýza sebepečlivěji, na spoustu věcí se vždy přijde až během vývoje (nemusí to bejt ani vina programátora, často je to vinou zákazníka a zadání, nebo šéfa :-)) a změny jsou tedy nutný.
                            V tu chvíli díky „optimalizovaný“ struktuře databáze začne člověk prskat jako kocour a buďto dělat věci natřikrát přes ruku, nebo přepisuje půlku aplikace. Proto radši nechám realitu tak jak chci, a případný „upravený“ dotazy si taham pomocí views či uloženejch procedur.

                            Traverzování kolem stromu je sice hezký, ale do tý doby, než člověk záznamy v daný tabulce chce i upravovat. Takovej update celý tabulky kvůli vložení jednoho záznamu je cool. Konkurenční transakce prakticky nemaj šanci.
                            Nemluvě o tom, kdybych náhodou chtěl logovat všechny změny provedené v databázi (odsypávat staré záznamy do vedlejších tabulek). Kvůli změně jednoho řádku kopírovat celou tabulku… Opět je to velmi dobrá technika a nezřídka ji používám, ale její použití je omezený.

                            Not in dotazy se daj, ten zápis mi ale nepřipadá jednodušší než
                            klasickej framework, co žere SQL.

                            Jinak opakuju, proti notorm nic menám a dokážu si představit spoustu příkladů, kde by to byla jedna z nejvhodnějších knihoven na přístup k
                            databázi. Jen se IMHO prostě nehodí na vše :-)

                            PS: A nad ťěma stored procedure se zamyslete, dopsat by tam šly snadno – podědit objekt tabulky tak, aby jako argumenty žraly argumenty SP. Ve větších kouscích software bych se aspoň osobně bez SP obcházel těžko…

                            1. Jakub VránaAutor příspěvku

                              Re: Pro jednoduché věci ano

                              Podporu pro uložené procedury si klidně dopište, je to open-source. Ale s API bude problém, protože uložené procedury nesdílí jmenný prostor s tabulkami, takže volání $db->$tableName() musí vždy přistoupit k tabulce a uložené procedury by se musely volat krkolomněji.

                              1. logik

                                Re: Pro jednoduché věci ano

                                No, v tom bych zrovna problém neviděl, protože i když jmenný prostor nesdílí, tak je imho prasečina je pojmenovávat stejně.

                                Asi bych to osobně implementoval tak, že někde v konfiguráku (škoda že php nemá aplikační server, tam by se krásně šlo vše načítat z db bez ztráty výkonu) názvy stored procedur. %db->nazev() by pak volal stored proceduru – pokud by byla v tom konfiguráku. Když by se to doplnilo ještě
                                speciální metodou _table($tablename) a _proc($tablename), tak by to řešilo i ty výjimky, kdy je člověk čuník, nebo nechce psát konfigurák.

                                V současnym projektu to moc nepoužiju, ale jestli budu někdy pracovat na projektu, kde se mi tadle knihovna bude hodit, tak si to dopíšu :-), bude to IMHO pár řádek kódu…

                              2. jos

                                Re: Pro jednoduché věci ano

                                co přesně znamená uložené procedury nesdílí jmenný prostor s tabulkami ?

                                jestli si měl na mysli to co já, tak je to závislý na implementaci

                                MSSQL:

                                create table dbo.foo
                                (id int not null)
                                GO

                                create procedure dbo.foo
                                as
                                select * from dbo.foo
                                GO

                                Msg 2714, Level 16, State 3, Procedure foo, Line 3
                                There is already an object named ‚foo‘ in the database.

                                1. Jakub VránaAutor příspěvku

                                  Re: Pro jednoduché věci ano

                                  Může být. Každopádně se na to NotORM nemůže spolehnout.

                      2. okbob

                        Re: Pro jednoduché věci ano

                        Pořadí spojování tabulek se u moderních plannerů řídí statistikou – kdežto u tebe zápisem – to bych viděl spíš jako krok zpět. Tak asi na projekty na které se nasazuje PHP to třeba úplně tragické být nemusí – už vzhledem k tomu, že NotORM vygeneruje indexy, které jsou pro některé programátory tabu. Což na jednu stranu je výhoda, na druhou stranu nevýhoda, poněvadž pro některé dál může zůstat db black box, což je špatně.

                        1. Jakub VránaAutor příspěvku

                          Re: Pro jednoduché věci ano

                          Jediný případ, kdy by se pořadí vyhodnocení mohlo lišit, jsou vazby 1:1, které jsou ojedinělé. Jinak u vazeb 1:N a M:N by se použil LEFT JOIN, který pořadí zpracování taky jasně určuje. U omezení výsledků jedné tabulky podle druhé tabulky se použije poddotaz, takže to je ponecháno v režii databáze.

                          NotORM žádné indexy negeneruje, na strukturu databáze vůbec nesahá. Dokonce by se obešel i bez cizích klíčů. Naopak strukturu databáze plně respektuje, takže její správný návrh zůstává nezbytným základem.

                          1. okbob

                            Re: Pro jednoduché věci ano

                            No já používám většinou INNER JOIN i na vazby 1:N. Použití INNER nebo OUTER JOINU nemá vztah ke kardinalitě vazby.

                  2. František Kučera

                    Re: Pro jednoduché věci ano

                    Ad „Ale jestli kvůli stejnému výpisu položím 1 dotaz (který přenáší hodně dat) nebo 3 dotazy (které přenáší málo dat), tak to bude velmi podobné“

                    Ty to ale bereš tak, že jakmile máš ty data v PHP, pracuješ s nimi „zadarmo“, že drahá je jen práce databáze. Ale tak to není. Sice ušetříš nějakou práci databázi, ale pak ji musíš udělat v PHP*

                    *) ono to vypadá snadno, použiješ hash-tabulku, ale i její sestavení něco stojí, je to v podstatě indexování (přičemž takto indexovaná data za chvilku zahodíš) a vyhledávání sice znamená napsat data[„klíč“], což je pár znaků v kódu, ale z hlediska výkonu to taky něco stojí. Proč by měl být tvůj kód v PHP efektivnější, než kód relační databáze? Ta může navíc používat mezipaměť, která přetrvává i mezi dotazy/požadavky.

                    1. Jakub VránaAutor příspěvku

                      Re: Pro jednoduché věci ano

                      Té práci se tak jako tak nevyhneš. Zkus si napsat kód, který vypíše všechny aplikace a k nim všechny jejich značky pomocí spojování tabulek. Bez polí se dá obejít jen velmi těžko a i když to uděláš, tak musíš použít přinejmenším nějaká porovnání.

                      Práce s hash-tabulkou je asymptoticky zadarmo. Každé vložení nebo načtení prvku proběhne v průměrném čase závislém pouze na délce klíče, která je konstantní, takže i celá operace je konstantní. Takže nasypáním N prvků do hash-tabulky a jejich vypsáním strávíš čas O(N) (tedy nějaká konstanta krát N) a lépe to nejde, protože na každý prvek si musíš sáhnout.

            2. František Kučera

              Re: Pro jednoduché věci ano

              „spíš bych ji pojmenoval SimpleORM“

              Já bych to ani SimpleORM nenazval – že to má některé nevýhody ORM, ještě neznamená, že to je ORM. Já tu nikde nevidím ty objekty, spíš mi to přijde jako jiný pohled na výsledkovou sadu. Jakubův název (NotORM) je tedy v pořádku*.

              „nesmí se to přehánět – je blbost generovat v SQL komplet html stránku.“
              Souhlas, v databázi se dá vytvořit nějaký „mezitvar“, třeba v XML – může to být lepší forma, než obyčejná výsledková sada (tabulka/matice).

              *) i když tahle móda negací…

              1. Jakub VránaAutor příspěvku

                Re: Pro jednoduché věci ano

                Pro mě mají ORM nevýhody dvě:

                1. Nutí mě vytvářet nebo generovat nějaké třídy, které mi jsou k ničemu.

                2. Kladou neefektivní dotazy.

                Ničím z toho NotORM netrpí. Co je to podle tebe?

                1. František Kučera

                  Re: Pro jednoduché věci ano

                  „Nutí mě vytvářet nebo generovat nějaké třídy, které mi jsou k ničemu.“

                  WTF?

                  „Kladou neefektivní dotazy“

                  V takovém případě můžeš ten dotaz „přebít“ vlastním – donutit ORM, aby použilo tebou napsané SQL (ukážeš mu cestu), ale mapování už zase provádí to ORM (udělá za tebe tu nudnou práci). Nevýhodou je spíš to, že zakrývají relační databáze, zvyšují složitost systému, znepřehledňují*, svádí k jednoduchým (a často hloupým) řešením…

                  *) ale zároveň i zpřehledňují – přidají totiž jednu horizontální vrstvu, ale ve „vertikálním“ směru aplikaci zase zjednoduší

                  1. Jakub VránaAutor příspěvku

                    Re: Pro jednoduché věci ano

                    Podívej se na NotORM jako sestavovač dotazů do databáze. Nic nezakrývá, nezesložiťuje, neznepřehledňuje a nevede k hloupým řešením. Prostě jen vytváří efektivní dotazy a posílá je do databáze ke zpracování. Plně respektuje strukturu databáze i myšlenku, kterou programátor kódem vyjádří, jen k tomu poskytuje pohodlné API.

                2. logik

                  Re: Pro jednoduché věci ano

                  1. A kdo jinej by měl vědět, např. co se s daným objektem dá dělat, jaké poskytuje možné akce, jaké má vlastnosti atd…? V současnym projektu je
                  poměrně velká část logiky právě v modelech postavených na ORM.
                  ORMM rozhodně není ten „blbej moloch“, kterej jen zesložiťuje apliakci a pokládá blbý otázky. Jen se prostě ORM nehodí na všechno a musí se vědět jestli, kdy a jak ho použít. Pak je to výtečnej nástroj zjednodušující programátorovi ži­vot.

                  2. Zajímavé – používám ORM, a rozhodně do DB špatný dotazy nepokládám
                  (teda, aspoň jsem o tom dosti silně přesvědčen),
                  Ono by koneckonců ani nebyl problém udělat ORM nad notORM :-)

                  1. Jakub VránaAutor příspěvku

                    Re: Pro jednoduché věci ano

                    1. Co se s objektem dá dělat a jaké poskytuje akce, určuje model. Třídy generované ORM ale tímto modelem nejsou, to je další vrstva navíc, která je podle mého názoru zbytečná.

                    2. Buď prosím konkrétnější. Uveď, jaký používáš ORM, jak ho používáš a jaké to položí dotazy. Ukaž to třeba na příkladu získání aplikací spolu s jejich autory a nálepkami, který je použit v příkladu.

                    1. logik

                      Re: Pro jednoduché věci ano

                      1. A kdo mi zabrání, abych jako model použíl třídu, kterou z ORM podědím?

                      2. Používám ORM vlastní výroby. Používá se zrhuba takto:

                      $apps=Applica­tions::find(a­rray(‚lmit‘ ⇒ 10));
                      $apps->findChild(‚au­tori‘)
                      $apps->findChild(‚na­lepky‘)
                      foreach($apps as $app)
                      {
                      echo $apps[‚nazev‘];
                      foreach($apps->childs[‚autor‘] as $autor)
                      echo $autor[‚jmeno‘];
                      foreach($apps->childs[‚nalepka‘] as $nalepka)
                      echo $nalepka[‚nazev‘];
                       }

                      Vygenerovany dotazy:
                      SELECT * FROM application LIMIT 10;
                      SELECT * FROM autor WHERE id IN (SELECT autor_id FROM applicationautor WHERE ID in (1,2,3,4,5,6,­7,8,9,10))
                      SELECT * FROM nalepky WHERE ID in (1,2,3,4,5,6,­7,8,9,10)

                      1. Jakub VránaAutor příspěvku

                        Re: Pro jednoduché věci ano

                        1. Nezabrání ti samozřejmě nikdo (tedy třeba kromě zaměstnavatele). Jen se tím typicky zhorší udržovatelnost a testovatelnost kódu – zvýší se jeho komplexnost.

                        2. Vidím, že se tvé myšlenky ubíraly podobným směrem jako moje při vývoji NotORM. Ale srovnej to s kódem použitým NotORM:

                        foreach ($db->application()->limit(10) as $application) {
                          echo $application["nazev"];
                          foreach ($application->applicationautor() as $applicationautor) {
                            echo $applicationautor->autor["jmeno"];
                          }
                          foreach ($application->nalepka() as $nalepka) {
                            echo $nalepka["nazev"];
                          }
                        }

                        Výhody NotORM vidím tyto:

                        • Není potřeba předem určovat, se kterými tabulkami se bude pracovat.
                        • Jednodušší API, které ale na druhou stranu dovoluje pracovat třeba i s pořadím autora pro danou aplikaci – tvé API zdá se vůbec nedovoluje přistoupit ke sloupci  applicationautor.poradi.
                        • Z databáze se přenesou jen ty sloupce, které se nakonec skutečně použijí.

                        Výhody tvého ORM nevidím žádné. Doporučuji proto přechod na NotORM.

                        1. logik

                          Re: Pro jednoduché věci ano

                          1) Pokud jsou optimální selecty, které získávají data z db složitý, mám dvě možnosti:
                          a) vždy je napsat ručně (byť za mírné podpory nějaké leighweight knihovny typu notOrm – protože v sestavení správných where a join podmínek mi žádná taková knihovna nepomůže)
                          b) zabudovat genrování správných sql dotazů přímo do modelů: opět k čemu mezivrstvu. Teda pokud nepočítám knihovny typu dibi apod, který trochu zpřehledněj SQL zápis.

                          Kód přitom zas tak složitej není, protože obecný ORM modely se napíšou jednou a pořádně se otestujou, a v jednotlivých konkrétní modelech se pak píše aplikační logika a popř. upřesnění, jak má knihovna se záznamem nakládat (např. podle kterých sloupců má kontrolovat uživatelská práva).
                          Až na výjimky se v nich nemusí použít SQL – ale když je potřeba, tak to jde.

                          Jelikož např. práva jdou efektivněji vyřešit když vím, že dělám select
                          na děti jednoho rodiče, od nějž jediného mohou zdědit práva než když to nevím, tak jaksi model do generování SQL dotazů tak jako tak šahat musí – takže si nedokážu představit, jak oddělit model a databázovou vrstvu a přitom zachovat efektivní generování uživatelských práv.

                          Nehledě na to, že např. pro získání podřízených objektů model taky musí nějak „vědět“, jaké jsou jeho podřízené objekty a jaká je relace mezi nimi. A od toho je ke generování SQL dotazů takovej kousek, že vrážet tam další vrstvu se mi zdá jako zesložitění, nikoli zjednodušení.

                          2) Samozřejmě, že je to v notOrm o něco jednodušší – taky je to knihovna pro jednoduchej snadnej přístup k databázi. Platí za to flexibilitou a možností rozšíření.

                          Není potřeba předem určovat, se kterými tabulkami se bude pracovat.
                          Na druhou stranu, když budeš chtít pracovat pouze s autorem první aplikace, tak se ti stejně natáhnou všechny. Což příliš optimální není. Já si můžu vybrat. Nebo si myslíš, že tam dopsat automatický přednačítání všech podřízených záznamů by byl takovej problém? Asi tak na tři řádky. Je fakt, že tam můžu dát parametr, jestli to rovnou přednačíst nebo ne, to neni blbej nápad.

                          API zdá se vůbec nedovoluje přistoupit ke sloupci applicationau­tor.poradi.
                          Ale umožňuje, akorát jsem to psal z hlavy, tak jsem se nekouk, že autoriaplikace neni čistě vazební tabulka. Samozřejmě můžu přistupovat i pomocí

                          $app->childs('applicationautor')->childs('autor')

                          Akorát mám možnost dopsat objektu i složitější vazbu, pokud potřebuju.
                          Např. „ignorovat“ MxN vazební tabulku, která je v podstatě implementační detail.

                          Přenášení jen použitých sloupců je zajímavá featura, nicméně zatím jsem se nedostal do situace, kde bych masivně načítal takové množství záznamů, že by mě to pálilo. Taková kontrola uživatelskejch práv je daleko větší zdržení a to se udělat musí. Nicméně je to hezký nápad a nevylučuju, že se jím někdy neinspiruju.

                          No á závěrem :-) výhody mojí knihovny nevidíš, protože nevíš, co umí. Samozřejmě když porovnáš lehkou knihovnu zaměřenou na co nejjednodušší načítání dat z db se složitějším frameworkem, tak jednoduchá kniohovna mírně vyhraje snadností zápisu… Stejně jako když si dá silniční speciál na dálnici závody s offroadem.

                          Fór je v tom, že u toho funkce Tvojí knihovny končej, zatímco mojí začínaj, ať jde o modifikaci dat (ať už s automatickou nebo manuální synchronizací s databází), kontrolu práv (poměrně dosti netriviální, pomocí ACL, uživatelských skupin a dědění oprávnění z nadřazených objektů), kontrolu kvót na počet podřízených objektů daného typu, validace dat apod. A to všechno vzhledem k databázi šetrným způsobem.

                          Netvrdím, že se to hodí vždy a všude – dovedu si představit spoustu projektů, kde bych notORM použil radši, ale i naopak – jen prostě tvrdím, že jsou případy, kdy ORM přístup umí využít výhody ORM, aniž by ztratil schopnost pokládat inteligentní dotazy.

                          1. Jakub VránaAutor příspěvku

                            Re: Pro jednoduché věci ano

                            Nějak nevidím, kde NotORM chybí jaká flexibilita a možnosti rozšíření. Jakákoliv logika se dá postavit NAD knihovnou, což považuji za čistší řešení než DO knihovny.

                            Když by se pracovalo jen s autorem první aplikace, tak se samozřejmě dá napsat $db->applicationautor("application_id", $application["id"]). Jenže tohle je potřeba výjimečně, takže jednodušší API ( $application->applicationautor()) je využito pro převažující variantu. Každopádně určovat to předem je zbytečné.

                            NotORM schopnost ukládání také má. Schválně by mě zajímalo, jak v tvém ORM vypadá kód, který položí dotaz UPDATE tab SET rank = rank + 1 WHERE group_id = ?. To je totiž pro většinu ORM prakticky neřešitelný problém a když už se dá vyřešit, tak se napíše mnohem víc kódu, než při ručním položení dotazu. NotORM i tohle zvládne elegantně.

                            1. logik

                              Re: Pro jednoduché věci ano

                              Ad NAD knihovnou – právě podstata toho příspěvku nad tím byla ta, že pokud potřebuju do databáze přistupovat se složitejma kritériama, tak si stejně drtivou většinu podmínek a SQL logiky musím napsat sám (respektive použít knihovnu, která mi ji vygeneruje). Čímž se mi naprosto ztratí výhoda oddělení SQL od modelu.
                              Kdyby šlo napsat

                              VytvořModely(NotormVýraz)

                              tak by to smysl mělo, jenže to prostě nejde. Respektive nejde tak, abych pokládal dotazy efektivně, aniž by NotOrm výraz generoval samotnej model (respektive tableModel – čili objekt popisující záznamy jednoho typu, ale nechci zabejhat do podrobností).

                              V tom cachování máš pravdu – knihovna je ve vývoji, takže tam dopisuju co potřebuju. Todle je rozumný, takže volitelný automatický přednačítání dle parametru už tam je. :-)
                              Že se to používá výjimečně ale neni až tak úplně pravda – např. zobrazuju seznam věcí a u prvního (nebo i prvních třech z třicíti) zobrazuju víc podrobností. (např. seznam letenek, u první zobrazim i
                              kde se přesedá atd…). AJAXem pak na rozklik zobrazuju podrobnosti u dalších záznamů…

                              Ad ukládání – psal jsem o možnosti volby automatický synchronizace s databází. Ty máš jenom manuální. Nebo jak by Ti fungovalo

                              $application["id"]=10;
                              $application->update()

                              :-)
                              Ale zrovna jak ukládání, stejně jako (fakultativní) přednačítání, jsou naprosto nedůležitý detaily – stejně jako já si můžu dopsat načítání, tak ty synchronní ukládání nebo možnost měnit idčka. O takovejdle „blbinách“ se imho nemá smysl bavit, je to jen honění trika co koho zrovna napadlo a implementoval.

                              Co se týče update rank = rank + 1, tak takovýdle dotazy jsou často způsobený špatnym návrhem datový struktury – akce jednoho objektu by neměly vést k úpravě celé databáze. Navíc pokud nemáš aplikační logiku v databázi, tak jsou často i nelegální (obcházej nějakej kus aplikační logiky, takže časem při úpravách kódu může dojít k nekonzistenci).

                              Nicméně i pokud je nutné je použít a mám aplikační logiku v modelu, tak jediný místo, kde můžu aspoň trochu legálně takovejdle dotaz položit, tak je v modelu. A tam mam přístup k plnýmu SQL. A nevěřim, že v NOTorm bude ten zápis o tolik jednodušší než v SQL.

                              Ono třeba v tom tvym případě – je to jednoduchej dotaz: ale já bych zas u toho např. musel řešit práva – můžu to vůbec udělat? A zajistit, že pro všechny ty záznamy bude hodnota rank+1 povolená, promyslet, co se stane když tydle dotazy poběžej dva najednou atd…

                              Nicméně, protože kromě samotnejch modelů používám i tableModely, tak
                              pokud bych takovýdle update potřeboval tak často, že by byl opruz je psát v čistym SQL, tak by nedalo moc práce tam tydle metody dopsat – metody na generování where podmínek mám, na generování update SQL taky.

                    2. Borek Bernard

                      Re: Pro jednoduché věci ano

                      Ad 1) Tohle se nedá říct obecně, pokud vytváříš aplikaci s bohatým doménovým modelem, nejen že není tato vrstva navíc zbytečná, ale dokonce se stává jsou z nejdůležitějších částí kódu vůbec. NotORM vypadá šikovně pro primárně read-only stránky, ORM má zase svou sílu v „plnohodnotných“ aplikacích. Možná jsi to tak i myslel, jen zde v komentářích nějak zapadl kontext.

  4. Patrik Štrba

    Cache

    Nebolo by lepšie pri ukladaní/loadovaní do/z cache robiť hash z toho namiesto ukladania celého dotazu ?


    $this->notORM->cache->load("$this->table;" . implode(",", $this->conditions));

    na


    $this->notORM->cache->load(md5("$this->table;" . implode(",", $this->conditions)));

    ???

    1. Jakub VránaAutor příspěvku

      Re: Cache

      Jistě by to šlo, ale přínos v podobně pevné délky klíče se mi zdá malý ve srovnání s tím, že by nebylo možné selektivně smazat záznamy týkající se nějaké tabulky nebo sloupce a poznat, co v cache vlastně je.

      1. logik

        Re: Cache

        S tim prozkoumávánim cache souhlasim, ale selektivně promazávat cache se stejně bude jen pro určitou tabulku či konkrétní dotaz – pak by mělo smysl uvažovat o dvojúrovňový cache [table][md5(con­ditions)] kde to md5kovaní by se dalo zapnout jen pro produkční server…

  5. Oldis

    Re: Databáze v PHP elegantně s NotORM

    a jak tahle knihovna resi omezeni vyberu zaznamu z tabulky jedne joinem dat z tabulky druhe?

      1. roman

        Re: Databáze v PHP elegantně s NotORM

        Autor tejto urcite zaujimavej kniznice ma velku prax v tvorbe PHP kodu, ale to mu nepomoze urobit lepsi nastroj, ako priamu tvorbu dotazov. Neda si vysvetlit, ze subselecty su do urcitych verzii MySQL(stupnovite) neefektivne a mysli si, ze eleganciou to nahradi. Objektovejsie sa to bude pisat, ale neefektivnejsie to bude fungovat. Je to pekna hracka a tak to aj treba brat.

  6. srigi

    Profiler

    Kcem sa opýtať či NotORM obsahuje profiler/rozhranie (najlepšie prepojitelne s Nette 0.9), kde zistim počet rq a ich znenie. Poprosim ukážku kódu. THX

    1. Jakub VránaAutor příspěvku

      Re: connect

      Nijak. Konstruktoru se předává již navázané připojení pomocí PDO (resp. Dibi), které NotORM využívá.

      1. jxp

        Re: connect

        Zajímavé. Proč Dibi a ne přístup k mysql co mám PHP nativně? Vždyť to musí NotORM spomalovat.
        Řeší NotORM zápis do tablulky (insert)?

        1. Jakub VránaAutor příspěvku

          Re: connect

          Výchozí připojení je přes PDO, které je stejně nativní jako extenze MySQL. NotORM se dá použít s více databázovými systémy, takže je nějaká sjednocující vrstva potřeba. Kdo používá Dibi (nebo nepoužívá PDO), tak ho může použít i s NotORM.
          Zápisy k dispozici volitelně jsou: http://www.notorm.com/#persistence

  7. phper

    pomoc prosím

    Mám tabulku dbtest v které jsou dva sloupce id (auto increment) a data
    for cyklem to chi po jednom řádku číst, když je to formulováno takto, tak
    $data = $dbtests->data[$i];
    mi laděnka hází chybu Undefined variable: dbtests
    nevíte někdo co s tím

  8. Sebastian

    výborný

    Dobrý den, bohužel v celé diskusi bych našel příspěvků, které by Vám nepsali, že NotORM je nesmysl, hloupost a (špatná) hračka, které se dají spočítat na jedné ruce.
    Přiznám se, že o existenci NotORM vím už delší čas, ale na první pohled se mi nelíbílo, že neni objektový, proto jsem jej nestudoval, spíše jsem se mu vyhýbal a zavíral jsem před ním oči.
    Ale dnes jsem si přečetl tento článek a příjde mi, že to neni hračka, pokud bych pracoval na nějaké projektu, kdy by byl pro mě přínosný, určitě bych po něm sáhnul jako po užitečném nástroji.
    Výborná práce.
    PS: Určitě by mu slušelo i možnost psát inserty ve stejné syntaxi, představte si situaci, kdy při vytváření nové aplikace chci zrovna i přidat novou nálepku. Vytvořím aplikaci → získám její id → vytvořím nálepku → získam její id → spojim je… :)

  9. talpa

    reseni je jeden select

    tohle je vazne prasecina, tohle vetsinou potrebujeme v jednom selectu a pak s tim dal pracujeme, efektivnejsi je ,se sql serveru dotazovat co nejmene a rovnou si vracet hotovou datovou kostku. To ze lidi neumi sql pak resi takovejma jak to nazvat… no…fuj

    1. Jakub VránaAutor příspěvku

      Re: reseni je jeden select

      To je omyl, jeden dotaz velmi často nejefektivnější není. Důvodem je, že se stejná data přenáší opakovaně. Pro příklad použijeme třeba výpis článků, kde u každého článku chci zobrazit do jaké kategorie patří (1) a které jsou u něj nálepky (N). Pokud jsou dva články ve stejné kategorii, tak se název kategorie (a všechny další případné informace, které ke kategorii potřebuji) přenáší znovu s každým článkem – to ještě nemusí být tak moc dat navíc. Hlavní problém způsobí nálepky, kdy se s každou nálepkou (jejichž názvy se také přenáší opakovaně) znovu přenáší kompletní informace článku – a to už je dat hodně.

      Podrobně jsem to rozebíral v článku Srovnání dotazů do závislých tabulek, kde je z obrázků dobře patrné, jak náročná komunikace u jednotlivých řešení je.

      Prasečina je pokládat lineární počet dotazů (při každém průchodu cyklem jeden). Konstantní počet dotazů je naopak asymptoticky ten nejefektivnější způsob. Někdy může být maličko horší než jeden dotaz, nikdy ale nebude řádově horší a naopak může být i řádově lepší.

Napsat komentář

Přihlásit se

Tato diskuse je již příliš stará, pravděpodobně již vám nikdo neodpoví. Pokud se chcete na něco zeptat, použijte diskusní server Devel.cz

Zdroj: http://www.zdrojak.cz/?p=3233