[ goran33 @ 22.05.2003. 23:59 ] @
Da li neko može da mi kaže šta je bolje i zašto - kad se slika smesti u bazu kao binarni fajl ili kad se unese samo putanja do slike. Do koliko zapisa bi bilo podnošljivo unositi slike kao binarne fajlove kada je brzina u pitanju?

Pitam zato što jedino tako znam da unesem sliku u bazu, tj. da neki korisnik sam prebaci sliku na server...
[ -zombie- @ 23.05.2003. 01:21 ] @
nije preporučljivo stavljati slike u bazu.. i nema nekog limita.. nije preporučljivo staviti ni jednu, a 100 puta je nepreporučljivije staviti 100 slika..
[ tOwk @ 23.05.2003. 03:54 ] @
Zombi, postoje razne baze. Sigurno ćeš negde naći i nekoga ko i disk i fajlsistem smatra specijalizovanom bazom.

Uostalom, ja bih baš voleo da čujem zašto je „nepreporučljivo“ staviti slike u BLOB?

Otežava bekap? Ne verujem. Umanjuje brzinu? Teško, čak najverovatnije suprotno.
[ -zombie- @ 23.05.2003. 04:14 ] @
i posle će mi goX briše deo poruke gde kažem da towk filozofira..


kakve be razne baze.. kakav je fs baza.. (ali neću da kažem da lupaš, pošto si u pravu.. ;)


kada neko postavi konkretno (ne filozofsko/teorisko) pitanje na php forumu, u 99% slučajeva misli na mysql bazu..


i baš me ubedi da je brže poslati upit iz php-a ka mysql serveru, on da pretraži indexe, da nađe u kom mu je to fajlu, na kom mestu, da iskopira, vrati php-u, php prosledi apačeu, i apače browseru, nego da apače pročita fajl i prosledi browseru..

[ goran33 @ 23.05.2003. 12:44 ] @
Upravo sam i mislio na Mysql bazu...
Korisnik npr. želi da ubaci svoju sliku na sajt, izabere fajl i slika se kao blob upiše u bazu i kasnije se iz baze "vadi" i prikazuje kao jpg/gif... Najlakše bi mi bilo da to ovako i ostavim, ali ako nije dobro šta treba da radim?

Kako da to uradim drugačije, tj. da se baš slika prebaci u neki folder na serveru, a da se putanja do njega upiše u bazu?
[ CONFIQ @ 23.05.2003. 13:19 ] @
Ako ne očekuješ da te hosting kompanija ne izbaci, lepo stavi u poseban direktorijum a u bazi čuvaj putanju, baš onako kako si naveo :)
[ bluesman @ 23.05.2003. 17:48 ] @
Citat:
goran33:
Upravo sam i mislio na Mysql bazu...
Korisnik npr. želi da ubaci svoju sliku na sajt, izabere fajl i slika se kao blob upiše u bazu i kasnije se iz baze "vadi" i prikazuje kao jpg/gif... Najlakše bi mi bilo da to ovako i ostavim, ali ako nije dobro šta treba da radim?

Kako da to uradim drugačije, tj. da se baš slika prebaci u neki folder na serveru, a da se putanja do njega upiše u bazu?


Koliko kapiram nije bilo reci da li moze vec sta je bolje. Naravno da moze, ali mislim da je zombie u pravu (provereno). Najbolje resenje, u bazi se cuva samo ime fotke, imas neku globalnu varijablu sa folderom gde cuvas sve fotke (na primer "images/") pa onda procitas iz baze ime fajla i samo ispises obicam <img> tag. Definitivno najbolje resenje, jer zamisli bazu od nekoliko stotina hiljada korisnika pa jos svaki ima po 5 fotki. Jos ako napravis da se fotke cuvaju u folderima sa pocetnim slovom, recimo fotke za usere "bluesman" se cuvaju u "images/b/l/" (ili jos dublje ako ocekujes vise korisnika) onda je to definitivno najefikasnije resenje.
[ tOwk @ 23.05.2003. 18:01 ] @
Sa zombijem bih se mogao složiti da se ne radi o sledećem.

Svako drugo predloženo rešenje je takođe uključivalo MySQL i isti postupak koji Zombi opisuje. Tek zatim (kada se pronađe ime fajla u kom se nalazi slika, umesto same slike), se još dodaje vreme potrebno da se taj fajl na disku pronađe. Znači, opet je MySQL+BLOB brži od MySQL+ime fajla+Apache.

Dalje, MySQL spada u server, i prema tome je stalno u memoriji. Takođe, ako su ti ljudi iz MySQL-a imalo pametni, sigurno su i sve baze keširane u jednoj heš tabeli, i istima se može pristupiti neposredno (čuva se npr. inode), što je mnogo brže od traženja fajla po imenu.

Znači, MySql + BLOB je sigurno brže rešenje.

Problem sa ovakvim pristupom je druge prirode: generisana HTTP poruka je sigurno lošija od one koju Apache sam pravi. Tako programer će najverovatnije zaboraviti da doda Content-Length, odgovarajući mime tip, itd. Neće biti moguće nastavljanje, i slično.

Zbog toga je rešenje sa otvorenim pristupom slikama na serveru najbolje (najpraktičnije) uz čuvanje samo imena fajlova u bazi, a ako se čitaju slike iz nekog direktorijuma koji nije javan (i tada postoje isti problemi sa HTTP porukom kao MySQL + BLOB), onda prednosti nema.

Ja filozofiram? Nikad, baš nikad!
[ -zombie- @ 23.05.2003. 21:06 ] @
znači, nema ništa dok se ja i towk ne pobijemo.. dobro, dolazim u bgd sledeće nedelje, pa se spremi..


elem, towk, na temu teoriskog dela problema bi mogao da raspravljam sa tobom, ali mislim da u konkretnom slučaju nema smisla..

ja ću da ti opišem praktičan slučaj kako se najčešće koriste slike..

imaš profil korisnika na dejting sajtu, ili opis proizvoda u nekom katalogu. kada korisnik klikne da vidi detalje o korisniku ili proizvodu, ti uputiš jedan sql upit tipa

SELECT ime, preziime, godište, grad, slika FROM ljudi WHERE id='$id'

odakle na stranici prikažeš te podatke, i ispišeš jedan <IMG/> tag. sad, ako ti je u polju slika lepo putanja do slike, onda lepo u <IMG/> tagu staviš <IMG src='$base_url/$slika' /> i browser uputi lepo novi zahtev apače serveru koji mu lepo pošalje sliku..

u drugom slučaju, da je polje slika BLOB sa samom slikom, prvo ga ne bi ni pitao u upitu, nego bi <IMG/> tag izgledao nešto ovako <IMG src='slika.php?id=$id' />, pa bi na novi zahtev browsera da prikaže sliku, apače ponovo morao da izvršava php skript, koji se ponovo povezuje na bazu, ponovo upućuje upit i prosleđuje ga nazad apaču, koji ga srećan prosleđuje browseru..


ako ti i dalje tvrdiš da je to brže.. onda mi ne preostaje nego da stvarno dođem da te prebijem..


u svakom slučaju -- i opet sam pobedio -- gejm boj.
[ tOwk @ 23.05.2003. 21:39 ] @
Sve to jako lepo zvuči kada ti pričaš, a ipak nije tačno (uključujući i deo o „prebijanju“ ;-).

Prvo da se (ne) složimo u sledećem: MySQL upit je „jeftiniji“ od čitanja fajla sa diska (razloge sam već objasnio: MySql valjda drži već mapiranu poziciju ka tim fajlovima baze, i samo čeka da neko nešto zatraži, i onda daje).

E sad, u tvom „praktičnom“ slučaju imamo sledeće: 1 php+1 mysql+1 slika (učitava je Apache sa diska, prvo tražeći fajl sa datim imenom, njemu dodeljene blokove na disku i sve što je u vezi sa tim). Ako koristimo MySQL, imamo 2 php + 2 mysql. Zato, početnu stranicu (1 php+1 mysql) možemo izbaciti iz poređenja, pošto je u tom slučaju ekvivalentno.

Preostaje nam „slika sa diska“ i php+mysql. Ako je MySql kvalitetno napravljen (u šta ne sumnjam), on je u stanju da pronađe podatke na disku bez izričitog zahteva operativnom sistemu.

Znači „slika sa diska“ = „saznaj blokove gde je smeštena slika“ + „učitaj blokove“, dok je „php+mysql“ = „saznaj blokove gde je smešten php fajl“ + „obradi php + mysql upit“ + „učitaj blokove“, tj. razlika je samo u dodatnom mysql upitu i obradi php-a. Ipak, kako je PHP u ovom slučaju mnogo manji od slike (pošto se samo radi o izvlačenju BLOB-a iz baze i ispisivanje istog, dva tri reda PHP koda), to su ova dva pristupa uporediva u najgorem, (kako Zombi kaže) „praktičnom“ slučaju.

Eto, slažem se da nije „sigurno“ brži (kako sam prethodno rekao), ali je bar (približno) iste brzine, a nikako sporiji. Ono na šta sam zapravo mislio je da je BLOB moguće više ubrzati, ako se radi samo o brzini. (Npr. sve tražiš u jednom upitu, uključujući i BLOB, i onda praviš HTTP poruku kao MIME multipart.)

Eto, kome je ovaj postupak logičniji i jednostavniji, ne treba da brine za brzinu, i to je suština. Nije to tako pogrešno kako mnogi hoće da prikažu, osim u onim stvarima koje sam ja izdvojio kao zamerke na samostalno generisanje HTTP poruke (a to važi za sve generisane stranice, ukoliko se ne vodi dovoljno računa).

Kad stigneš u Beograd, javi ;-)
[ CONFIQ @ 23.05.2003. 23:03 ] @
Uhhh tOwk...
Ajde razmisli,


to show db images::
- the image is first read from the data file into MySQL record buffer
- from the record buffer the image goes into the socket
- the application reads it from the socket into its internal buffer
- the contents of the internal buffer are forwarded to the user


file system, not even super highly optimized:
- the image is read from the data file into internal buffer of the web
server.
- the contents of the internal buffer are forwarded to the user

From: faqts.com


Then:
Another issue is that you either stream the data from the database (which means you hold a db handle until the consumer finishes consuming), buffer in memory with associated bloat, or buffer on the filesystem with associated overhead.

If it is in the filesystem, you can mmap the file and return it as a whole and have the kernel deal with paging in the data and streaming it out which is a big win.
From: redhat.com


I da ne nabrajam još...Nisam našao nikoga ko misli da je bolje držati slike u BLOB-u (sem tebe naravno .-) )
Rekao si, SQL to drži u memoriji ali kolko dugo će da drži u memoriji nisi naveo, isto nisi naveo da treba preko socketa da prenese apache-ju pa apache-i end-useru...

A posle se ljudi pitaju, 'Ali zašto me je verat izbacio. Kako je loš ovaj Verat...'
[ tOwk @ 23.05.2003. 23:27 ] @
To ti je uključeno u „MySQL upit“, pošto to sve spada u „to“.

Naravno, da si dao primer udaljenog MySQL-a, gde se to radi preko mreže, razlika bi već bila znatna, a ovako i dalje mislim da je to čitanje preko soketa brže od čitanja i pronalaženja fajla. Prosto, pročitati podatke iz MySQL BLOB-a je brže (nebitno da li malo ili puno) nego pročitati čitav fajl sa diska. Ukoliko to nije tačno, onda je MySql brlja, i ne treba ga ni za šta koristiti, već za sve treba koristiti fajlove (osim ukoliko je problem zauzeti prostor, ili su relacioni upiti od suštinskog značaja). Čak i tada bi onda samo trebalo implementirati algoritme za to, a podatke smeštati na disku (npr. direktorijum „članovi“ sadrži fajlove „confiq“, „towk“, „zombie“,... a svaki od tih fajlova sadrži o njima podatke, umesto jedne tabele u MySQL-u).

Znači, u tvom primeru sa faqts, prvi korak (za „db images“) je laganiji od prvog koraka servera, a druga dva koraka su jednaka sporijem od ta dva (pošto se događaju istovremeno, tome služe soketi), a svaki od ovih je takođe brži od prvog koraka direktnog čitanja. I eto, tu sad imamo 2 brža koraka+1 isti korak, a pri neposrednom čitanju imamo 1 sporiji korak+1 isti korak. Zašto bi 1 sporiji korak morao biti brži od 2 „brža“, zaista ne znam, ali vi neprestano tako tvrdite. Obratite pažnju na to da je seek time diska (čitaj: pronalaženje slike na disku) za nekoliko redova veličine veći od seek time-a za memoriju (čitaj: soket, pronalaženje fajla za mysql bazu,...).

Takođe, nisam rekao da MySQL kešira čitav sadržaj baze, već reference na blokove na disku. Pri čitanju običnog fajla, prvo se mora pronaći u kojim blokovima se taj fajl nalazi, a to je sporije od MySQL upita (tj. trebalo bi da bude, zaista nisam isprobavao).

No, možda je zaista MySQL sporiji, ali to je onda njegov problem, a ne moj :-P
[ tOwk @ 24.05.2003. 02:19 ] @
Evo još jedne besmislice u CONFIQ-jevom citatu:
Citat:

Then:
Another issue is that you either stream the data from the database (which means you hold a db handle until the consumer finishes consuming), buffer in memory with associated bloat, or buffer on the filesystem with associated overhead.

If it is in the filesystem, you can mmap the file and return it as a whole and have the kernel deal with paging in the data and streaming it out which is a big win.


Eto, „mmap“ je divan i savršen mehanizam, a „buffer in memory“ je „bloat“. Znači, u prvom slučaju je to loše, a u drugom dobro???
[ bluesman @ 27.05.2003. 00:35 ] @
Zasto moderator brise negativne komentare o svojim postovima? Odakle mu pravo?

Da rekao sam da si tvrdoglav k'o...
[ Ivan Stanojevic @ 27.05.2003. 13:01 ] @
ne vidim razlog zasto bi neko drzao slike u bazi, osim mozda ako hoce da zastiti fajlove na serveru ili nesto slicno???

zamisli da imas 1000 slika u bazi, i da sada trebas da promenis nesto na 10tak slika... moras da ih vadis iz baze, pa da ih vracas... a ako su na disku samo ih pronadjes u folderu...




[ bluesman @ 28.05.2003. 13:29 ] @
Da, bravo, i to sam zaboravio. Zamisli da imas 1 milion slika...
[ tOwk @ 28.05.2003. 13:35 ] @
Napraviš plug-in za gnome-vfs da čita direktno iz baze, i zatim pomoću Nautilus-a, Gimp-a ili bilo kog drugog programa koji podržava gnome-vfs URI-je: otvaraš kao i svaki drugi fajl.

Ili, napraviš dodatak za Photoshop da direktno čita iz baze, ako si već navikao na njega.

Neko reče da sam tvrdoglav? :-P
[ CONFIQ @ 28.05.2003. 14:56 ] @
Citat:
tOwk:
Evo još jedne besmislice u CONFIQ-jevom citatu:
Citat:

Then:
Another issue is that you either stream the data from the database (which means you hold a db handle until the consumer finishes consuming), buffer in memory with associated bloat, or buffer on the filesystem with associated overhead.

If it is in the filesystem, you can mmap the file and return it as a whole and have the kernel deal with paging in the data and streaming it out which is a big win.


Eto, „mmap“ je divan i savršen mehanizam, a „buffer in memory“ je „bloat“. Znači, u prvom slučaju je to loše, a u drugom dobro???

Taj "besmislen" citat što si rekao, napisao je Jeff Davis (mali progooglaj pa vidi ko je on), i totalno sa slažem sa njim, slike u DB je pumpanje memorije dok mmap lepo pročita fajl od prvog do poslednjeg bita, šta tu ima loše?

Nema šta da nastavljam, stvarno ništa lično, ali samo hoćeš da dokažeš da imaš drugačije mišljenje, ali ovo nije u pitanju nečije mišljenje nego argumenti.I bezveze nastavljamo i vrtimo se u krug tako da je ovo moj poslenji post na ovom topicu.
[ tOwk @ 28.05.2003. 15:06 ] @
Eeee... Pa pročitaj to malo pažljivije.

mmap() je zapravo „buffer in memory“, i tu nema šta. Znači to je ista stvar (MySQL sigurno učitava fajlove pomoću mmap()-a, ali unapred), samo što je u jednom slučaju ocenjeno kao „bloat“, a u drugom kao „prednost“.

Znači, loš argument.

Izvinjavam se samo što sada zaista nemam vremena da tražim ko je taj, i ne sumnjam u njegovu kompetentnost, ali to ne znači da mu je svaka izjava tačna (svi greše, čak i ja, ali niko nije pokazao da je tako i u ovom slučaju :-).
[ Dejan Topalovic @ 30.05.2003. 16:10 ] @
Iz MySQL manuala sa www.mysql.com :
- When using a normal web server setup, images should be stored as files. That is, store only a file reference in the database. The main reason for this is that a normal web server is much better at caching files than database contents. So it it's much easier to get a fast system if you are using files.

- In many cases it's faster to access data from a database (using a live connection) than accessing a text file, just because the database is likely to be more compact than the text file (if you are using numerical data), and this will involve fewer disk accesses. You will also save code because you don't have to parse your text files to find line and column boundaries.

Dakle, to kazu ljudi koji stoje iza MySQL-a.
Dalje, ako bi trebao napraviti backup baze, kako bi izveo to u slucaju da je baza velika 1-2-3...n+ MB/GB ? Jesi li ikad to pokusao? Ja nisam uspio "normalno" napraviti backup jedne baze, koja je iznosila 224 MB (da li zbog manjka memorije u kompjuteru, da li zbog preopterecenja database enginea, da li zbog preopterecenja servera na kojem se nalazi baza... ne znam). A zamisli da se u bazi nalazi barem 10 000 slika od koja je svaka prosjecno 50 kb, pa jos dodaj neke tekstualne informacije.. Na sta bi to licilo? Teorija je jedno, a praksa drugo.

Ako bi snimao sliku u BLOB, onda to ispada snimanje fajla u fajl (BLOB u bazi je takodje fajl).

Evo jos nekoliko komentara:
- Data from a database is retreived one row at a time so you have to
wait for each image. Storing the path in the database allows you to
fetch a row, spawn a child process to fetch the image, and continue to
fetch rows from the database while the child processes handle getting
the images.
- Mysql will not cache the images. The OS however will cache disk
reads.
- If you need to fetch the files from the database your app needs to wait
until it has recieved the data. If you only store name/path info it will
take less time to fetch the data, ship it off to the browser which can
start fetching the images without connecting to the database again.

Sounds pretty logical.. and it gets worse if your site is hosted by an ISP
who is using a database server running on a seperate box..

Citat:

Napraviš plug-in za gnome-vfs da čita direktno iz baze, i zatim pomoću Nautilus-a, Gimp-a ili bilo kog drugog programa koji podržava gnome-vfs URI-je: otvaraš kao i svaki drugi fajl.

Ili, napraviš dodatak za Photoshop da direktno čita iz baze, ako si već navikao na njega.

Neko reče da sam tvrdoglav? :-P

Ma da... Zasto jednostavno, kad moze komplikovano.
Citat:

Znači, u tvom primeru sa faqts, prvi korak (za „db images“) je laganiji od prvog koraka servera, a druga dva koraka su jednaka sporijem od ta dva (pošto se događaju istovremeno, tome služe soketi), a svaki od ovih je takođe brži od prvog koraka direktnog čitanja. I eto, tu sad imamo 2 brža koraka+1 isti korak, a pri neposrednom čitanju imamo 1 sporiji korak+1 isti korak. Zašto bi 1 sporiji korak morao biti brži od 2 „brža“, zaista ne znam, ali vi neprestano tako tvrdite. Obratite pažnju na to da je seek time diska (čitaj: pronalaženje slike na disku) za nekoliko redova veličine veći od seek time-a za memoriju (čitaj: soket, pronalaženje fajla za mysql bazu,...).

Demagogijom i zbunjivanjem neces nista postici, jer u svemu tome nema ni "a" od argumenta koji bi prakticno bio prihvatljiv. Ja mislim da ne zelis priznati da nisi u pravu, da ne bi time slucajno "izgubio ugled sveznajuceg" i samim time povrijedio svoj ego. Tvrdoglav jesi, ali na svoju stetu.
Citat:

No, možda je zaista MySQL sporiji, ali to je onda njegov problem, a ne moj :-P

Eh sad, pokusavas se izvuci politickim odgovorom, jer si uvidio da je pohranjivanje slika u bazu neefikasnije od pohranjivanja linka u bazu, a samog fajla na filesystem.
[ tOwk @ 30.05.2003. 16:45 ] @
Idemo redom.

Ovo prvo (što si podebljao) je zaključak, a kasnije su argumenti, pa ću tu dati odgovor.

Zatim, bekap se radi veoma lako, i ne znam zašto je to tebi bio problem:
tar cvzf bekap.tar.gz /usr/local/mysql/var/baza

Ono sa „snimanjem fajla u fajl“ mi nije jasno: zar snimanje slike u fajl nije isto „snimanje fajla u fajl“?


Zatim daješ konkretan opis rada MySql baze, i to je napokon „protivargument“. Znači, naš program u PHP-u koji koristi MySql je tako dizajniran da blokira („sinhroni rad“) proces dok ne završi. „Spawn a child process“ ima zaista mnogo prednosti, ali tek na višeprocesorskim mašinama (na jednoprocesorskim se samo dodaje vreme potrebno za context-switch).

Tek onda ide najvažniji argument: MySQL „ne kešira slike“ (pretpostavljam da se tu misli da ne kešira poziciju BLOB-a na disku, što je bio jedan od mojih osnovnih argumenata, vidi gore), dok OS kešira pristup disku (mada, i MySql pristupa disku preko OS-a ;-P). Znači, zbog ovoga moje tvrđenje nije tačno, i to je sve što je trebalo reći.

I onda se pominje opet sinhroni rad programa koji pristupa bazi, ali se kaže da će tada samo MySql brže završiti, a ne da će i ceo postupak proći brže (vidi moju analizu gore).

Naravno, već sam napomenuo da razmatram slučaj kada se MySql-u pristupa preko socket-a, i da je u slučaju udaljene MySql baze BLOB svakako neefikasniji (opet, vidi gore).

Ono što si ocenio kao „demagogiju i zbunjivanje“, jasno je da nisi shvatio. No, izgleda da ne poznaješ dovoljno dobro tu tematiku na tom nivou (što znači da si „vernik“ :-), pa nisi uspeo da povežeš tekst koji si citirao, sa onim što sam ja napisao.

Pored toga, drago mi je da misliš da sam bar pre ove teme uživao „ugled sveznajućeg“ (bar kod tebe, ako ni kod koga drugog). Hvala.
[ Dejan Topalovic @ 30.05.2003. 20:06 ] @
Citat:

Zatim, bekap se radi veoma lako, i ne znam zašto je to tebi bio problem:
tar cvzf bekap.tar.gz /usr/local/mysql/var/baza

Jeste ako imas pristup shellu i prava da uradis takav backup.
Sta ako nemas, nego su ti jedine mogucnost preko PHPmyAdmina ili recimo preko MySQL Fronta ?
U slucaju da zelis prebaciti bazu na neki drugi hosting, sta onda?
[ -zombie- @ 31.05.2003. 20:59 ] @
prestanite da se svađate, inače ću opet zaključati temu.. (a ti towk ako je otključaš, žaliću se NJemu.. ;)

elem, stripy, to što phpmyadmin ne ume da lepo dumpuje velike baze to nije problem ni mysql-a, ni slika u bazi, nego baš phpmyadmin-a.. preporučujem ti da napraviš svoju skriptu za dumpovanje baze.. ništa komplikovano.. (i pažnja, nemoj da čitaš sve podatke u memoriju, nego ih čitaj jedan po jedan red iz baze, i odma štampaj..)