20
Jan

Ukládat obrázky do DB???

Tento post chci napsat již dlouho. Ale pořád jsem buď neměl čas nebo chuť či odvahu. No ale nakonec se hvězdy dostaly do správné konfigurace a píšu.
 
Slyšel jsem hodně názorů ohledně ukládání obrázků do databáze (nebo obecně souborů, ale většinou se toto řeší s webem apod.). Zajímavé je, že většina lidí argumentuje stále tím samým a vždy říkají, jaké to má ohromné nevýhody. Nicméně nikdy jsem ještě neslyšel názor, který by přihodil i nějaké výhody a provedl zamyšlené porovnání.

Proč tedy všichni tak striktně odmítají uložení obrázků do DB? První argument, který každý vytasí je rychlost resp. pomalost. Nedělal jsem žádné podrobné testy pro určitou platformu, ale je jasné že to musí být o něco pomalejší je přece další vrstva mezi aplikací a souborem. Dalším argumentem je většinou velikost DB, to je celkem nepopiratelné. A nakonec “na bedně” máme ještě – trochu slabší, ale … – že “taková” data do DB nepatří.

Nejsem odpůrcem ani zastáncem ani jedné strany (i když otevřeně říkám, že neodmítám ukládání obrázků apod. do DB). Pojďme se ale podívat na vítěznou trojku a zkusit se nad tím zamyslet. Tedy třetí argument, ten mi připadá úplně “nejblbější”. Proč by proboha obrázky v DB nemohly být? Jsou to přece data jako každá jiná a chci-li s nimi takto pracovat není na tom nic špatného. Další. Velikost databáze. Jasně, když jsou tam data, musí místo zabrat. Kdyby byly na disku, tak taky místo budou zabírat. Je pravda, že s větší DB se hůře pracuje (zálohy, obnova, přesuny, …), ale neviděl bych to jako velký problém – můžeme ho přece lehce vyřešit např. rozdělením. A osobně nemám s velikostí problém – a pokud by snad nějaká DB mělo mít problémy s tím obsluhovat “velkou” DB nezaslouží si nic než zahodit. No a první – pomalost. Nevím o kolik procent mi toto sníží výkon, takže budu spíš polemizovat. Podívám-li se na to, ale z druhé strany, tak jako tak dříve nebo později nebude rychlost vyhovovat. Buď je třeba posílit HW nebo použít mozek – např. cacheování. Když to tak vezmu, tak s obrázky v DB si akorát trochu zkracuji tu cestu do fáze, kdy mi výkon nebude stačit. Pokud půjde použít mozek, paráda, můžu to lehce vyřešit. Pokud půjde o HW a nedělám projekt, u kterého nečekám růst (kdo by to dělal?), tak s růstem bude určitě třeba povýšit i HW. Ale je pravda, že všechny tyto věci jsou zbytečné nebudou-li obrázky v DB. Dobře tento argument beru – nemůžeme jej popřít ani potvrdit.

Co se ale podívat na výhody uložení v DB? První co mě napadne je určitě výhoda v podobě transakčního zpracování. Nikdo mi nevymluví, že transakce jsou skvělá věc. Pokud máte na aplikaci, která právě taková data zpracovává není nic lepšího než využít všech možností transakcí a constraintu apod. věcí. Nemusím se pak spoléhat na aplikaci, že vše udělá správně. Můžu to nechat na DB a můžu si taky DB updatovat přímo z konzole, což se někdy může velmi hodit. Další věc co mě napadá je zálohování a archivace. Pokud mám jednotné úložiště, vše je jednodušší. Co dál? Co třeba přístup z více míst najednou? Mám-li už jednou přístup do DB mám rovnou i přístup k obrázkům (ne že by nešlo vzdáleně pristupovat na FS, ale když už do DB pro jiná data musím, je to pak o starost méně). No a poslední věcí (co mě napadlo, né celkově) jsou práva. Když už jsem se patlal s přístupem k jiným datům v DB, tak udělat to nad tabulkou “obrazky” nebude mnoho práce navíc.

Chápu, že celý tento text je poněkud kontroverzní, a určitě přide někdo, kdo řekne “ty si ale pako, obrázky do DB nepatří a prostě nemáš pravdu” – já netvrdím, že tam patří (nebo nepatří), jen jsem se chtěl podívat na argumenty, kteří zarytí odpůrci používají.

Nejsem zastánce ani jednoho extrémního řešení, vždy si to chce celou věc pořádně promyslet.

There's 14 Comments So Far

  • Borek
    January 20th, 2007 at 13:51

    Ahoj Jirko,> Zajímavé je, že většina lidí argumentuje stále tím samým a vždy říkají, jaké to má ohromné nevýhody. Nicméně nikdy jsem ještě neslyšel názor, který by přihodil i nějaké výhody a provedl zamyšlené porovnání.Dovol mi upozornit tě na článek “Binaries Belong in the Database Too” ( http://www.sitepoint.com/blogs/2006/10/15/binaries-belong-in-the-database-too/ , mnoho zajímavého je taky v komentářích). Jinými slovy, v dnešním světě těžko budeš s nějakou myšlenkou první.> A osobně nemám s velikostí problém…Tak to jsme všichni rádi :)

  • cvalik
    January 20th, 2007 at 15:00

    Ja k tomu len tolko, ze keby to bola taka blbost preco cela filozofia WSS a MOSS je takto postavena ???Veskery Content (suboru, obrazky….)su ulozene v DB a nejak moc nesledujem pokles vykonu pri praci… Dokonca mozete pouzivat veci ako Fulltextove vyhladavanie :)

  • rob
    January 20th, 2007 at 20:14

    Já přihodím něco ze světa Oracle.Existuje tam datový typ BFILE, což je defakto BLOB, ale jeho obsah není uložený v databázi, ale jako soubor na disku.Přitom jsem schopen se souborem v databázi pracovat více méně jako s normálním sloupcem – např. ho fulltextově indexovat (on to nemusí být jen obrázek, že) a výhoda transakčního zpracování je také zachována.Osobně si myslím, že HiRes obrázky (o velikosti jednotek až desítek MB) v databázi být nemusí (ale mohly by – záleží na konkrétním scénáři), ale třeba náhledové obrázky nebo textové dokumenty už rozhodně ano.

  • mjurek
    January 20th, 2007 at 21:00

    S tim vykonem – vykon cteni je zhruba stejny, kritickou operaci je sekvencni nacteni z disku a to je +- stejne. A mam-li dost pameti, je to superrychle, protoze je to vetsinou nekde nacache’ovane – bud jako DB stranka anebo v cache souboroveho systemu. Zapis do databaze bude urcite pomalejsi, uz jenom proto, ze se vse pise 2x (do logu a do souboru). Zase je ale mozne mit transakci mezi obrazkem a ukladanymi metadaty a to se mi zda nedocenitelne – a obrazky se stejne malokdy zapisuji, daleko casteji se ctou.

  • janb
    January 21st, 2007 at 01:57

    Dalsí problém bych viděl s tím, že DB server je většinou jeden (někdy více, ale stojí nehorázné peníze) a tedy je to často nejslabší článek celého webu. Webové servery se poměrně levně dají “duplikovat” a vytvořit tak celou farmu webových serverů s jedním DB serverem. S DB serverem, kde požaduji onu transakčnost, to už tak jednoduché není.Tím samozřejmě ztratím onu transakčnost, ale to je u obrázků často zbytečný luxus (prostě to nebývá potřeba) – i když výjimky se jistě najdou.Takže právě u aplikací, kde očekávám růst, se může zbytečné zatěžování DB dost prodražit.

  • lazo
    January 22nd, 2007 at 03:27

    Pokusim se ze svou troskou do mlyna. Osobne jsem presvedcen, ze ukladat binarni data to databaze by nemela byt implicitni strategie. Rozhodnouti ulozit binarni data do databaze by melo byt az po zvazeni skutecnych prinosu takoveto operace. Proc?SQL Server je engine pro spravu strukturovanych dat. Informace o souborech (jmeno, cesta, velikost apod.) jsou strukturovana metadata a s temi umi SQL dobre a efektivne pracovat. File system (FS) to umi presne opacne – ze strukturovanymi daty si nevi rady a s bloby mu to jde skvele. Proc nepouzit vhodny nastroj k tomu k cemu je urcen?Z Vaseho clanku jste IMHO vystihl jediny silny argument, a to sice transakcni zpracovani BLOBu. To je IMHO dobry argument. Nicmene je treba rici, ze “Evil is in details”. Napriklad UPDATETEXT ci WRITETEXT jsou nelogovane operace pokud je databaze v Single recovery modu, pocet zamku uvalenych na BLOB pointery uvnitr transakci je v ramci jedne databaze omezen ci zamykani radku se lisi podle toho, zda se data BLOBu ulozi v ramci datoveho radku ci nikoliv. Pokud temto detailum rozumi cely team – skvele, neni co resit. Ale to, jak zapsat a smazat soubor znaji opravdu vsichni.Ostatni argumenty uz tak jednoznacne nejsou. Oblibeny argument je backup – vse lze zalohovat najednou. Jiste, ale backup se provadi hlavne proto, abyste byl schopen data rychle obnovit. A pokud mate poskozeny pouze jeden soubor (ci podmnozinu souboru), tak musite obnovit celou databazi (pokud mate SQL 2005 tak to uz ovsem neni pravda a mate body i zde). To, ze lze vse zazalohovat najenou je sice pohodlne ale obnova dat – a k tomu je preci backup delan predevsim – jiz tak snadna neni. Obnovit podadresar ci samostatny soubor ze zalohy file systemu je IMHO nesrovnatelne primocarejsi proces.Pristup k datum z jednoho mista – Ano, ale pokud mate data v databazi, tak k nim musite pristupovat pres nejake API. .DOC soubor ve file systemu otevrete z Wordu kdekoliv, ale pokud je tento soubor ulozen v databazi, tak potrebujete mit dalsi software, middleware, ktery Vam .DOC soubor vystreamuje a pak ho teprve muzete otevrit. POkud je to to, co potrebujete, proc ne.Bezpecnost – s timto argumentem nesouhlasim. Pristup k danemu sloupecku v databazi pro jednotlive uzivatele\skupiny musite resit pomoci pohledu ci ulozene procedury. Cim vice uzivatelu\skupin a sloupecku tim vice pohledu. Ulozene procedury mohou trosku pomoci. V souborovem systemu je to mnohem jednudussi a flexibilnejsi (napriklad se pridelena\odebrana prava podedi v cele hierarchii adresarove struktury). Zmena prav v souborovem systemu je jednoducha. Zmena prav uvnitr databaze muze znamenat nejen vytvoreni novych pohledu ale pripadne i prekodovani SELECTu uvnitr techto pohledu ci ulozenych procedur. Nachylnost k chybe (vypublikovat to, co nema byt vypublikovano) je IMHO v pripade databaze pomerne velka (prave proto, ze se to hure spravuje). V databazi nelze az tak snadno zjistit kdo ma pristup k danemu sloupci s dokumentem coz dela take audit mnohem slozitejsim. Vzhledem k tomu, ze souborovy system primarne pracuje s granualitou “jeden soubor” je IMHO sprava pristupovych prav v souborovem systemu jednodussi a bezpecnejsi. Auditovani v souborovem systemu je automaticka operace, v databazi si ji musite nepsat sam. Navic audit SELECTu je moznou pouze z ulozenych procedur a je extremne slozity na vyvoj i udrzbu.Fulltext – to lze samozrejme i ve FS bez SQL Serveru (a tudiz dalsich nakladu na licence a hardware).Add) cvalik>> ze keby to bola taka blbost preco cela filozofia WSS a MOSS je takto postavena ???Az budete mit ve WSS tisice souboru (coz neni dnes vubec zadny problem, spocitejte si soubory na Vasem typickem souborovem serveru), tak se ozvete s postrehy. A drzim Vam palce, pokud budete chtit prenest soubory ve WSS\MOSS z mista na misto at uz uvnitr WSS\MOSS site ci mezi jednotlivymi site (ano, budete to programovat pres WSS\MOSS API a bude to legrace). WSS\MOSS je koncipovan jako web server nikoliv kvuli genialite ukladani dat do databaze ale IMHO primarne kvuli tomu, ze WSS\MOSS poskytuji komunikacni infrastrukturu pro tluste klienty z baliku Office. Sila WSS\MOSS je v kolaboraci (nekolik uzivatelu koordinovane edituje jeden PowerPoint soubor, napriklad, a spolecne vidi zmeny v real time). Tato rizena kolaborace potrebuje nejaky middleware a tento middleware musi mit kontrolu nad editovanym souborem. To je dle meho nazoru duvod, proc jsou data ukladana do SQL databaze – pokud by byla data na file systemu, tak by primy pristup k souboru pres file system celou tuto kolaboracni architekturu rozhodil pouhym otevrenim souboru mimo tento middleware. Ulozenim dat do SQL database je zarucen pristup k datum pres jednotne API – middleware, ktery ridi kolaboraci tlustych klientu. Vse ostatni ve WSS\MOSS je omacka, ktera vznikla kvuli tomu, ze soubory ve WSS\MOSS musi byt mozne take nejak spravovat, pokud mozno co nejpodobneji jako ve file systemu, protoze na to jsme vsichni zvykli.I cteni BLOB dat z databaze je IMHO mnohem pomalejsi, protoze BLOBy nejsou ulozeny jako sekvencni stream, ale jako BTree slozena z 8KB stranek.

  • viga
    January 22nd, 2007 at 10:15

    S temi transakcemi to tak uplne nebude, prace s blobem neprobiha v ramci transakce. Ale zduraznil bych jinou vyhodu pro binarni data v databazi. Binarni data v databazi zabiraji mene mista nez v souborovem systemu, protoze velikost vyuziteho prostoru v databazi neni nasobkem velikosti stranky (4.096 kB) jako v souborovem systemu. Obzvlast velke uspory mista tak lze dosahnout v situaci, kdy mame opravdu hodne malych souboru.

  • cincura.net
    January 22nd, 2007 at 10:29

    Borek >>> Dovol mi upozornit tě na článek “Binaries Belong in the Database Too”> (> http://www.sitepoint.com/blogs/2006/10/15/binaries-belong-in-the-database-too/> , mnoho zajímavého je taky v komentářích). Jinými slovy, v dnešním> světě těžko budeš s nějakou myšlenkou první.Ja ani nechtel byt prvni. Proste jsem do toho chtel jen pichnout.> Tak to jsme všichni rádi :) Cekal jsem, kdo prvni se toho chytne. ;) rob >>> Já přihodím něco ze světa Oracle.> > Existuje tam datový typ BFILE, což je defakto BLOB, ale jeho obsah> není uložený v databázi, ale jako soubor na disku.Jo, to se da take dobre vyuzit. > Osobně si myslím, že HiRes obrázky (o velikosti jednotek až desítek> MB) v databázi být nemusí (ale mohly by – záleží na konkrétním> scénáři), ale třeba náhledové obrázky nebo textové dokumenty už> rozhodně ano.Ja bych dam dal klidne i HiRes obrazky, pokud by to melo smysl.mjurek >>> urcite pomalejsi, uz jenom proto, ze se vse pise 2x (do logu a doOno zalezi jakou DB clovek pouziva. Nektere DB nepouzivaji log (treba Firebird ;) ) a pak se to zapisovat 2x nemusi.> souboru). Zase je ale mozne mit transakci mezi obrazkem a ukladanymi> metadaty a to se mi zda nedocenitelne – a obrazky se stejne malokdy> zapisuji, daleko casteji se ctou.Taky dobry postreh.lazo >>> Pokusim se ze svou troskou do mlyna. Osobne jsem presvedcen, ze> ukladat binarni data to databaze by nemela byt implicitni strategie.No tak to samozrejme. ALe myslim, ze to plati obecne. Kdyz nepremyslim, driv nebo pozdeji si namlatim kokos.> Z Vaseho clanku jste IMHO vystihl jediny silny argument, a to sice> transakcni zpracovani BLOBu. To je IMHO dobry argument. Nicmene je> treba rici, ze “Evil is in details”. Napriklad UPDATETEXT ci> WRITETEXT jsou nelogovane operace pokud je databaze v Single recovery> modu, pocet zamku uvalenych na BLOB pointery uvnitr transakci je v> ramci jedne databaze omezen ci zamykani radku se lisi podle toho, zda> se data BLOBu ulozi v ramci datoveho radku ci nikoliv. Pokud temto> detailum rozumi cely team – skvele, neni co resit. Ale to, jak zapsat> a smazat soubor znaji opravdu vsichni.Tohle bych rekl je implementacni detail one DB. Muzu pouzit desitky jinych a vse muze byt jinak. > Ostatni argumenty uz tak jednoznacne nejsou. Oblibeny argument je> backup – vse lze zalohovat najednou. Jiste, ale backup se provadi> hlavne proto, abyste byl schopen data rychle obnovit. A pokud mate> poskozeny pouze jeden soubor (ci podmnozinu souboru), tak musite> obnovit celou databazi (pokud mate SQL 2005 tak to uz ovsem neni> pravda a mate body i zde). To, ze lze vse zazalohovat najenou je sice> pohodlne ale obnova dat – a k tomu je preci backup delan predevsim -> jiz tak snadna neni. Obnovit podadresar ci samostatny soubor ze> zalohy file systemu je IMHO nesrovnatelne primocarejsi proces.Ja jsem tak nejak implicitne predpokladal (ale nejak jsem to nerekl), ze kdyz uz by neco takoveho bylo a nebylo to 100 obrazku po 1kB, tak bych to ulozil do separatniho uloziste (tedy samostane DB nejcasteji). A samozrejme inkrementalni zalohy jsou dobry pomocnik.Ale je pravda, ze obnovovat 10 souboru z FS je lehci nez 2GB databazi. > Pristup k datum z jednoho mista – Ano, ale pokud mate data v> databazi, tak k nim musite pristupovat pres nejake API. .DOC soubor> ve file systemu otevrete z Wordu kdekoliv, ale pokud je tento soubor> ulozen v databazi, tak potrebujete mit dalsi software, middleware,> ktery Vam .DOC soubor vystreamuje a pak ho teprve muzete otevrit.> POkud je to to, co potrebujete, proc ne.To je pravda. Zde jsem zase ja zabredl k implementaci a predpokladal jsem webove pouziti, takze man-in-the-middle byl vlastne samotny “web”. > Bezpecnost – s timto argumentem nesouhlasim. Pristup k danemuDiky za to!> sloupecku v databazi pro jednotlive uzivatele\skupiny musite resit> pomoci pohledu ci ulozene procedury. Cim vice uzivatelu\skupin a> sloupecku tim vice pohledu. Ulozene procedury mohou trosku pomoci. V> souborovem systemu je to mnohem jednudussi a flexibilnejsi (napriklad> se pridelena\odebrana prava podedi v cele hierarchii adresarove> struktury). Zmena prav v souborovem systemu je jednoducha. Zmena prav> uvnitr databaze muze znamenat nejen vytvoreni novych pohledu ale> pripadne i prekodovani SELECTu uvnitr techto pohledu ci ulozenych> procedur. Nachylnost k chybe (vypublikovat to, co nema byt> vypublikovano) je IMHO v pripade databaze pomerne velka (prave proto,> ze se to hure spravuje). V databazi nelze az tak snadno zjistit kdo> ma pristup k danemu sloupci s dokumentem coz dela take audit mnohem> slozitejsim. Vzhledem k tomu, ze souborovy system primarne pracuje s> granualitou “jeden soubor” je IMHO sprava pristupovych prav v> souborovem systemu jednodussi a bezpecnejsi. Auditovani v souborovem> systemu je automaticka operace, v databazi si ji musite nepsat sam.> Navic audit SELECTu je moznou pouze z ulozenych procedur a je> extremne slozity na vyvoj i udrzbu.Zde jsem myslel, ze primo aplikace bude ridit pristup k danym datum a to ze je “jednodussi”. Kdyz uz totiz umi (jakkoli) dostat ven napr. informace o souboru, je uz jednoduche dostat ven i ten sloupec s blobem.Ale jak ted nad tim premyslim, je to dost sporne. Asi by zalezelo hodne na konkretnim pouziti. > I cteni BLOB dat z databaze je IMHO mnohem pomalejsi, protoze BLOBy> nejsou ulozeny jako sekvencni stream, ale jako BTree slozena z 8KB> stranek.ulozeni> A to jako ve vsech DB? No to snad ne. :) Velikost stranky je mozne (nekdy) specifikovat a stejne tak interni “poskladani” blob-stranek muze byt odlisne. Napr. FB v blob page header udrzuje odkazy na dalsi stranky, kde jsou vlastni data. Pri cteni vezme ukazatele do pameti a precte spravna mista. Hotovo (lehce zjednoduseno). Pozn: Ale je pravda, ze blob header page muze mit 2 (tedy i vice, ale 2 vetsinou staci) urovni (aby se tam ukazatele vesli).cteni> Jak jsem psal, zadne testy jsem nedelal. Ale kdyz budu mit soubor defragmetovany, a pak to bude taky problem, pac budu litat po disku jak blazen. A stejne pokud budu mit (tedy treba pro FB ;) ) stranky “za sebou” muzu se priblizit sekvencnimu cteni.

  • cincura.net
    January 22nd, 2007 at 10:36

    viga >>Jaktoze bloby nejsou pod transakcni spravou?S tou DB strankou jsem to nejak nepochopil… Ledaze by nektera DB umela bloby cpat do DB stranek jeden-za-druhym (ale tolik DB enginu tak detailne neznam, abych mohl posoudit).

  • viga
    January 22nd, 2007 at 15:14

    >Jaktoze bloby nejsou pod transakcni spravou?Mozna jsem se nepresne vyjadril, ale ted koukam ze presnejsi vysvetleni ohledne tech transakci uz predemnou napsal lazo.>S tou DB strankou jsem to nejak nepochopilJde o paging na strane souboroveho systemu. Proste kazdy soubor zabira na disku velikost, ktera je nasobkem 4096 bajtu (Win), takze i soubor, ktery ma 1 bajt zabere na disku 4096 bajtu. Databaze tuto nevyhodu eliminuje, protoze je to vsechno v jednom souboru.

  • cincura.net
    January 22nd, 2007 at 15:22

    viga >>1> to je ale implementacni detail jednoho DB enginu, existuje jich halda, ktere to umi.2> no ale kazdy DB soubor je rozdelen an DB stranky (aspon doufam, ze to tak vetsina DB ma) a kdyz do blob stranky vrazim 1 bajt, stejne uz zbytek zadna jina data nevyuziji – leda zeby DB engine umel cpat data do stranek jaksi “za sebou a porad”, ale to by bylo asi neefektivni.

  • TomasHolanek
    January 24th, 2007 at 02:08

    Divím se, že zde nikdo nezmínil využití v replikacích. Scénář – oddělené pracoviště vs. centrála + replikace dat v nějakých intervalech => nemusím se starat o přenášení souborů. Ale jinak jsem zastáncem ukládání souborů mimo dtb.TH

  • Petr Lazecky
    January 24th, 2007 at 12:50

    Ve Vasem scenari pracoviste vs. centrala by to mohl byt dobry argument. Resenim by ale stejne tak mohlo byt sdileni souboru pres nejaky intranet, napriklad pomoci HTTPS (zalezi na citlivosti dat), a neprovadet replikaci vubec (kazdy klient si stahne je to, co potrebuje a vzdy aktualni verzi – proc to komplikovat replikaci?). Osobne jsem nezminil replikaci, protoze na platforme Windows lze replikovat i na urovni souboroveho systemu a tudiz k tomu nepotrebuji databazi. To je mozne ale pouze uvnitr dane site nikoliv pres internet. V pripade obrazku ukladanych do databaze (scenar o kterem se zminuje clanek) a pak renderovanych nekde na webu je ukladani obrazku do databaze IMHO scestne, protoze “replikaci” v tomto pripade obstara HTTP protokol + nejaky ten klient v podobe knihovny nad timto protokolem, ktery provadi caching. S trochou humoru byste mohl rici, ze diky HTTP + knihovny mate k dispozici snapshot pull replikaci, receno v hantyrce SQL Serveru :-) . Obrazky jsou tedy na file systemu a pres HTTP se “replikuji”.

  • Marcel
    February 21st, 2007 at 09:49

    Jeste je tu jedne duvod pro ano obrazku v DB. Pokud mate vice webovych serveru (web farma). Pak prace s obrazky na jednotlivych serverech nebo sdilenych discich je pomerne problem. Hlavne ukladani vs nastaveni prav.

Share your thoughts, leave a comment!