45 komentářů k článku SQLite: Databáze pro váš web:

  1. Tomáš

    Neumí správně řadit?
    Nevím no, ale neumět správně česky řadit mi přijde jako solidní stopper :)

    1. Vlastimil PospíchalAutor příspěvku

      Re: Neumí správně řadit?
      Ve většině aplikací to ani nemusí vadit. Vždy se výstupní seznam dá natáhnout do seznamu v PHP a seřadit tam. Běží to ve stejném procesu, takže je jedno jestli sort dělá SQLite nebo PHP.

      Další možností, o které budu psát v některém z dalších dílů, je napsat funkci pro české porovnávání a řazení v PHP a přidat ji k PDO. Je to jen několik řádek navíc.

      1. Honza Kral

        Re: Neumí správně řadit?
        Ne, to skutecne neni jedno. PHP (ani zadny jiny genericky jazyk) nikdy nebude tak efektivni jako DB ktera muze radit za pomoci indexu, jedna se o rozdil radu.

        1. Vlastimil PospíchalAutor příspěvku

          Re: Neumí správně řadit?
          Bavíme se stále o webové aplikaci? Mnoho jich vůbec nepotřebuje řazení podle abecedy. Když se podívám do běžných frameworků, tak tam nacházím všechno možné, ale potřeba řazení podle abecedy tam zas tak častá není.

          Indexy v databázi začínají být zajímavé až od několika tisíc položek. Pro menší tabulky je zpravidla lepší se jim vyhnout, protože je výhodnější sekvenční scan.

          1. janek

            Re: Neumí správně řadit?
            Potřeba řadit nijak nesouvisí s frameworkem. Prostě mám x uživatelů a chci prvních dvacet seřazených podle abecedy.

            1. Vlastimil PospíchalAutor příspěvku

              Re: Neumí správně řadit?
              Je možné použít rozšíření ICU, viz odkaz od Davida Grudla.

      2. Martin Sura

        Re: Neumí správně řadit?
        „Ve většině aplikací to ani nemusí vadit“.

        To je snad vtip ne? Tzn, že když budeš chtít kdykoliv použít třeba stránkování, tak to budeš dělat tak, že vezmeš z db všechny položky a pak je v php/pythonu seřadíš?

        Nebo jsem něco špatně pochopil?

  2. Martin

    Velmi pomalé vložení řádku do tabulky
    Ahoj. Postupně zapojuji SQLite do našeho projektu, který původně pracoval s MSSQL, ale z různých důvodů chceme alespoň určitou část převést na SQLite. Mám ale obrovské problémy s výkonností. Je normální, aby zápis jednoho řádku do jednoduché prázdné tabulky trval cca 200 ms, někdy je to ale i více než 1 sekunda? Databáze je před vytvořením tabulky zcela prázdná (soubor o nulové délce). SQL vypadá takto:

    DROP TABLE IF EXISTS „dataA“;
    CREATE TABLE „dataA“ (
    „id“ integer NOT NULL PRIMARY KEY AUTOINCREMENT,
    „minute“ integer NULL,
    „sample“ integer NULL
    );

    INSERT INTO „dataA“ („minute“, „sample“) VALUES (9, 2);

    Vždyť to jsou jen dvě celá čísla a databáze i tabulka je jinak prázdná (i když je pak plnější, doba zápisu zůstává přibližně stejná). Potřebuji takto po jenom řádku zapisovat cca 50x každých 10 s, což databáze vůbec nestíhá. Zkouším to z C++ aplikace přes Kompex zapouzdření i wrapper z Admineru (přes PDO), zdá se, že jde o vlastnost samotné databáze. Když to samé udělám v MS SQL Server 2008 Express na stejném počítači, časy jsou neměřitelně malé! Můžete někdo tento primitivní příklad vyzkoušet, jestli máte také tak pomalou odezvu, nebo poradit, co mám v příkladu špatně? Dík, Martin

    1. Vlastimil PospíchalAutor příspěvku

      Re: Velmi pomalé vložení řádku do tabulky
      Stačí všech 50 řádek umístit do jedné transakce. Stejný způsob se používá i při hromadném importu dat.

      Vysvětlení: SQLite je souborová databáze a z důvodu zachování konzistence dat po každém zápisu vyčkává zhruba tak dlouho, než se plotna disku otočí dokola. Toto chování se sice dá vypnout, ale hrozí nekonzistence dat v případě výpadků napájení – může být prohozeno pořadí potvrzených transakcí. U serverů s UPS by k tomu nemělo dojít a je možné vypnutím atributu zvýšit výkon.

      Atribut se vypíná příkazem „PRAGMA synchronous=OFF“, ale v daném případě určitě bude stačit zmíněné uzavření do transakce.

      1. Martin

        Re: Velmi pomalé vložení řádku do tabulky
        Dík za odpověď. Takto to vysvětlují i v SQlite FAQ. Tam ale píší 60 transakcí za sekundu, které by mi stačily. Je normální, že to trvá cca od 170 ms do více než jedné sekundy v podstatě náhodně? Přijde mi, že to nějak souvisí s aktuálním využitím stránkovacího souboru a možná i s antivirem. Zkoušeno na sqlite3, dvou různých počítačích (WP7 64 a XP Professional), třech různých discích, v obou případech zapnutý rezidentní Norton antivirus (nemohu vypnout, jsou to servery) a občas se to přehoupne přes sekundu. To je pro mě nepoužitelné, protože jde o systém kontinuálního měření. Zabalení do jedné transakce mohu použít jen omezeně, jde o zápis z různých aplikací. Ty musí jet nezávisle mnoho let v kuse i bez údržby v zapečetěné bedně. Proto se SQLite zdálo být dobrou volbou oproti MSSQL a jiným strojům, u kterých jsme po měsících či letech provozu vždy narazili na nějaký problém i při nastavené automatické údržbě. Zřejmě budu muset napsat vlastní engine s frontou pro údaje z jednotlivých aplikací, který všechna data za časový interval uloží v jedné transakci. Tím se ale část výhod SQLite ztratí. Nezabezpečená verze nepřichází v úvahu, data musí přežít výpadky napájení, updaty jednotlivých aplikací za běhu, požár i povodeň.

        1. Vlastimil PospíchalAutor příspěvku

          Re: Velmi pomalé vložení řádku do tabulky
          A co „PRAGMA synchronous=OFF“? Pokud to jsou časově nezávislé záznamy, tak by to fungovat mělo bez potíží.

          Nevím sice, co pohledává ten antivirus na serveru, ale i ten by to mohl mít na svědomí. Je možné, že tu databázi kontroluje na viry po každém zápisu? To by mohlo vysvětlit ty prodlevy.

          1. okbob

            Re: Velmi pomalé vložení řádku do tabulky
            V pg konferenci se docela pravidelně objevují varování před použitím antivirů na db serverech. S tím, že v extrémních případech mohou způsobit ztrátu dat – pokud si usmyslí, že Vaše databáze je virus.

        2. Vlastimil PospíchalAutor příspěvku

          Re: Velmi pomalé vložení řádku do tabulky
          Malý test na notebooku, hodnoty jsou pouze orientační:

          – Základní nastavení – 6 INSERTů za sekundu
          – PRAGMA synchronous=OFF – 7000 insertů za sekundu
          – PRAGMA synchronous=OFF + transakce – 40000 insertů za sekundu
          – PRAGMA synchronous=ON + transakce – 15000 insertů za sekundu

          Jak je vidět, v základním nastavení je INSERT velmi pomalý.

          1. Martin

            Re: Velmi pomalé vložení řádku do tabulky
            Těch 6 zápisů mám průměrně také, ale občas některý přeleze sekundu a to i na druhém počítači s vypnutým antivirem. Myslím, že tam je to způsobeno stránkováním ve Windows 7 při hodně zaplněném disku. No nic, nějak se s tím vypořádám. PRAGMA synchronous=OFF použít nemohu z výše uvedených důvodů. Server u nás je „pro všechno“, jede na něm kdeco od FTP přes webové služby, několik druhů vzdálených ploch, Historian a testovací aplikace. Připojuje se tam „kdekdo“, ale je poměrně řídce využívaný, takže antivirus je na něm správně. Jsme příliš malá firma na zaplacení někoho, kdo by se server staral. Mimochodem drobný offtopic – netušíte někdo, jak se mohlo stát, že Apache jednoho dne náhle nefungoval, protože port 80 obsadil IIS? Sám od sebe v době, kdy na serveru nikdo nepracoval.

          2. uplnej vypatlanec

            Re: Velmi pomalé vložení řádku do tabulky
            a jake je zakladni nastaveni ?! kdyz pri ON i OF to jsou tisice za sec ? ( ptam se, protoze SQLite take pouzivam)

      2. Honza Kral

        Re: Velmi pomalé vložení řádku do tabulky
        NE, dalsi blud! nejedna se o zadne cekani na plony nebo neco podobneho, s otacenim disku to nema spolecne naprosto vubec nic. Jedna se o to, ze kvuli zachovani ACID se vola fsync (odtud koneckoncu i nazev nastaveni pro vypnuti). Jestli chcete zvysit rychlost zapisu, pouzijte proste DB ktera je k tomu urcena (skoro vsechny ostatni) a nebo zmente sve pozadavky – ne rdbms ale cache s rdbms featurami a pouzijte in-memory sqlite (‚:memory:‘ jako db name).

        1. Martin

          Re: Velmi pomalé vložení řádku do tabulky
          Dík, tohle zní rozumněji než plotna otáčející se pětkrát za sekundu. Jsou ale in-memory tabulky přistupné z různých procesů – mohu je umístit do sdílené paměti, aniž bych příliš měnil zdrojáky SQLite? Synchronizaci je vyřešená, k souběhu nedojde. Předpokládám, že zkopírování změn na disk pak bude opět v čase jedné transakce, tedy těch průměrně 170 ms, což by mi bohatě stačilo.

  3. David Grudl

    Co se to děje se Zdrojákem?
    Nechtěl jsem remcat, když se tu objevil „Velký letní test nevíme-vlastně-nikdo-čeho“, protože jsem chápal, že když má Root komiks, Zdroják chce taky bavit. Nechtěl jsem remcat ani u článku „Shrnutí soutěže WebTop100 2012“, jehož obsah by vydal na jeden ne příliš zajímavý tvít. Ale úvod do SQLite na konci roku 2013? V němž se dozvíme, proč používat SQLite pro web: „SQLite má velmi příznivou licenci Public Domain. Můžeme ji tedy bez omezení používat v komerčních i nekomerčních aplikacích.“ WTF?

    Chápu, že podobně kvalitní autory, jako je třeba Jakub Mrozek, je těžké najít, ale nebylo by lepší jít cestou překladů, jako byly třeba výborné články Honzy Javorka o Pythonu? Tohle už totiž dost vrže…

    (Disclaimer: slíbil jsem a následně nedodal Zdrojáku nemalé množství článků.)

    1. Vlastimil PospíchalAutor příspěvku

      Re: Co se to děje se Zdrojákem?
      A navíc nehodlám v dalších dílech ani zmínit Dibi či Nette. To je troufalost, co?

    2. head

      Re: Co se to děje se Zdrojákem?
      Ide to dole vodou odkedy sa zdrojak oddelil od roota. Uz sem chodil len ked sa velmi nudim a nepamatam, kedy som tu naposledy nasiel nieco zaujimave…

  4. blizz

    OODBMS / pst RDBMS
    hladam objektovu databazu do, ktorej by sa dali jednoducho serializovat / deserializovat .NET objekty, ktore by zaroven vystupovali ako recordy v tabulke… databaza by zvladala aj relacny aj objektovy pristup mala by podporu OQL. skusal som Caché ale odradil ma objectscript – co je objektivne velmi hnusny jazyk a gui nastroje, ktore vyzeraju ako notepad z roku 92.

    1. Vlastimil PospíchalAutor příspěvku

      Re: OODBMS / pst RDBMS
      Co třeba Redis? Není to sice přímo objektová databáze, ale jednodušší objekty a kolekce se do ní ukládat dají. Lua snad bude lepší.

  5. Petr Prchal

    Chjo...
    Mozna by bylo dobry popsat jeste nejakou zastaralejsi technologii, aby mladez videla, jak jsme to meli tezke…

    Zdrojaku prosim, zacni vydavat zas nejaky lidsky clanky, ORM test PHP frameworku sotva skoncil a uz zas je to spatny.

  6. jakubvrana

    Využití SQLite
    SQLite při zápisu zamkne celou databázi, během čehož nemůže kdokoliv další nic zapisovat, ale ani číst. To nevadí u mobilních a dalších jednouživatelských aplikací, ale na webu to může být fatální problém, protože s databází typicky potřebuje pracovat mnoho uživatelů najednou. Pro většinu webových aplikací je tedy SQLite kvůli výkonnostní charakteristice nevhodné (celkem rychlý jednouživatelský režim nevyváží blokující víceuživatelský režim).

    Chybějící podpora Unicode bude často také problém. Samozřejmě si můžeme data setřídit v hostitelském jazyku, to ale znamená nejprve načíst všechna data z disku a zabrat jimi spoustu paměti. Dotaz ORDER BY name LIMIT 10 při existenci indexu nad sloupcem name ve správném způsobu porovnávání načte z disku a zabere v paměti maximálně 10 řádek. Při chybějící podpoře požadovaného porovnávání to znamená z disku načíst všech, třeba 1000000 řádek, které jsou v tabulce. Je to problém nejen z výkonnostního pohledu, ale i kvůli komplikaci kódu.

    Není pravda, že SQLite 3 je doporučeno používat pouze prostřednictvím PDO. Extenze sqlite3 je plnohodnotnou alternativou.

      1. jakubvrana

        Re: Využití SQLite
        Odkazovaný bug je opravený, metoda ve zdrojácích PHP skutečně je. Nemyslel jsi nějaký jiný?

    1. jirkakosek

      Re: Využití SQLite
      Zdá se, že historie se musí opakovat. Princip SQLite pro webové aplikace mi připomněl skoro 15 let starou historku, kdy se aplikace napsaná v ASP + Access zasekla, když ji začalo používat více uživatelů najednou. Lidi, pokud chcete na webu používat databázi, tak něco pořádného, a ne něco, co si tam šudlá a zamyká jeden soubor.

      1. Vlastimil PospíchalAutor příspěvku

        Re: Využití SQLite
        Myslím si, že na tom SQLite není hůř než XML databáze a XQuery.

        1. jirkakosek

          Re: Využití SQLite
          Má cenu na tohle odpovídat?

          Problém SQLite je v tom, že je to embeded databáze ne databázový server, ke kterému se připojují klienti. Pro více zatížené webové aplikace, kdy do databáze přistupuje obsluha více požadavků najednou, není koncept SQLite z principu vhodný. Naopak je SQLite vhodné, jako úložiště na klientovi – ať už třeba pro nativní mobilní aplikace, nebo volané z JS v prohlížeči, …

          Podobně jako u relačních databází i u XML databází existují embeded a serverové produkty.

          1. Vlastimil PospíchalAutor příspěvku

            Re: Využití SQLite
            Zamykání databáze se provádí pouze při zápisu. Pokud je zapnuta volba WAL, tento zápis neblokuje čtení z jiných vláken. Ve frontě tedy čekají pouze vlákna, která chtějí zapisovat.

            Číst je možné simultánně z mnoha procesů, vzájemně se neblokují.

            V článku jsem jasně uvedl, že SQLite je vhodná zejména tam, kde výrazně převažuje čtení nad zápisem. Článek je v redakčním systému zapsán jednou, pak už je zpravidla pouze čten.

            1. jakubvrana

              Re: Využití SQLite
              Režim WAL je ve výchozím nastavení vypnut. V článku o tom není ani slovo, takže začátečník (pro kterého je článek určen) použije SQLite tak, jak je přednastavena, a bude si myslet, že se bude chovat v souladu s tím, co je uvedeno v článku. To ale nebude.

              1. Martin

                Re: Využití SQLite
                Ahoj Jakube. Máš naprostou pravdu, že pro běžné použití na webu není SQLite vhodná. Ale třeba mně článek pomohl a hlavně diskuse k němu. Potřebuji databázi, která bude zdarma, bezúdržbová, pro zápis přístupná z průmyslové aplikace a pro čtení přes webové rozhraní, nejlépe z Admineru. Nic lepšího než SQlite jsem zatím nenašel, protože MySQL, MSSQL i další „dospělé“ databáze se ukázaly pro mnohaleté kontinuální bezúdržbové použití v uzavřené bedně (jednoúčelový průmyslový počítač pro sběr dat, kam mohu často jen na jednom TCP portu díky bezpečností politice u většiny průmyslových koncernů) nevhodné. Divil by ses, jakou setrvačnost má průmyslová IT oblast a i 20 let staré noviny se občas hodí. Mimochodem měl jsem pár námětů na diskusi k Admineru 3.7, ale asi tam starší diskuse už nečteš, tak se zeptám ještě tady: Lze v novém Admineru vypnout „mobilní“ zobrazení na mobilním zařízení? Víš o chybičce, kdy se u krátké obrazovky zápatí píše přes data a roluje s nimi nahoru? Lze pro sqlite dodělat podporu triggerů na pohledu? Lze pro sqlite dodělat podporu importu adminer.sql.gz v jedné transakci (import tabulky s několika tisíci řádky teď trvá skoro celý den a zasekne na tu dobu na serveru přístup k sqlite databázi – viz diskuse tady nahoře). Nebo exportu do gz „obaleného“ transakcí? Samozřejmě mohu sql editovat ručně a zabalit do gz, ale většina editorů má s velmi dlouhými textovými soubory problém. Ideální by bylo nastavit v Admineru možnost „obalit transakcí každých 1000 insertů“ nebo něco podobného s možností nastavení této konstanty.

  7. honza

    sqlite funguje
    Samozrejme, ze sqlite funguje i ve viceuzivatelskem modu. Jak je v diskuzi spravne uvedeno, je treba pouzivat transakce a prepare statements a ve vyhodnocovani reagovat na SQLITE_BUSY.

  8. Martin

    Ještě dotaz na znalé SQLite
    Ahoj. Občas mám výpadek v aplikaci, která nyní jako jediná zapisuje do SQLite databáze, když současně čtu z Admineru (přes PDO). Je to v pořádku? Děje se to dost zřídka a zatím jsem neodchytl výjimku, nějak jí vnitřně obslouží Kompex wrapper, ale občas je v zapsaných datech díra (chybí cca 1 řádek z každých 50000, když jich zapisuji v jedné transakci okolo 1,5M). Debugger VS se zastaví v obsluze výjimky, ale zatím jsem nezjistil, odkud pochází, výjimky jsou tam řešené dost zmateně. Myslel jsem, že zámky jsou jen v době zápisu. Ono je to tak, že čtení může u SQLite 3 v defaultním nastavení znemožnit zápis? Nemělo by to v takovém případě čekat na timeout? Ten mám defaultní, což je, myslím, jedna minuta. Nebo je pro zápis jiný než pro čtení?

    1. Vlastimil PospíchalAutor příspěvku

      Re: Ještě dotaz na znalé SQLite
      Po přepnutí databáze do režimu WAL by zápis již neměl blokovat souběžné čtení a k těmto chybám by již nemělo docházet.

  9. Martin

    Doplnění
    Oprava: Není to v celé v jedné transakci, ale rozděleno do několika po zapisovaných 14400 řádcích (denní záznam s deseti řádky za minutu). Jak je vůbec možné, že v takovém případě chybí v tabulce jednotlivé řádky? Indexy jsou zrušené a znovu vytvořené po ukončení poslední transakce.

  10. Martin

    Pochopil-li jsem to dobře, mělo by to řešit nastavení PRAGMA journal_mode=WAL. Otestuji a uvidím, teď už vím jistě, že šlo o zámek databáze pro zapisující aplikaci při čtení z jiné aplikace.

Napsat komentář

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: https://www.zdrojak.cz/?p=9478