Forum Moderators: coopster

Message Too Old, No Replies

Saving images in PHP: Blob vs. File

         

asantos

4:45 pm on Dec 10, 2008 (gmt 0)

10+ Year Member



Hi, im developing a contact network service. There will be around 50.000 users (each one has only 1 picture).

Would it be better to have their pictures on files (jpg) in a directory?
/avatars/38423.jpg
/avatars/12631.jpg
/avatars/02837.jpg

Or is it better to save them on blob fields in a mysql db?

LifeinAsia

4:55 pm on Dec 10, 2008 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



I always vote for directory. Otherwise, your database backups will take a lot longer than necessary. As well if/when you ever need to do a full restore of your DB.

asantos

8:32 pm on Dec 10, 2008 (gmt 0)

10+ Year Member



good point.

Vali

5:28 pm on Dec 11, 2008 (gmt 0)

10+ Year Member



depends on the number of images you have.
If you only have a few, and are not added by the user, put them in some folder.
If they are added by the user, or have a ton of them that need to change, put them in the database. It will be easier to manage later on.

Anyango

9:04 pm on Dec 11, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Agreed with LifeinAsia.

Just that i think you might want to manage some subdirectories in your pictures folder, like with every directory containing maybe like 500 max images. Imagine having to FTP to a directory (for any reason) that contains 50,000 Images, easily capable to hang many of the FTP clients even just while listing directory entries

asantos

10:12 pm on Dec 11, 2008 (gmt 0)

10+ Year Member



Anyango:
Good point, too.

Maybe i could categorize them by letter and number. Users that start with an "a" go to /A/*.jpg

And so on. Since there are 25 letters and 10 numbers, i should have 35 directories.

50.000 images divided into 35 directories is around 1400... that's more manageable for the ftp client.

janharders

12:38 am on Dec 16, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Or you can calculate the directory by looking at the id, e.g.
$folder = $id - ($id % 1000);
should get you one folder for every 1000 images, e.g.
0 for id 0 - 999
1000 for 1000 - 1999
2000 for 2000 - 2999
etc

and I, too, vote for a directory. Agreed, it's nice to have everything stored in one place so that a db-move is all you need etc pp but there's another thing: you'll need a php-script to give an image to the client, that's one extra script to run for every image you display and that can add up pretty fast. direct file delivery by the webserver is much, much faster than executing a php-script that connects to a database, queries a table, gets a row and prints the content of a blob.

asantos

10:54 pm on Dec 16, 2008 (gmt 0)

10+ Year Member



janharders,
i love your solution. bad news is that the ID of the user can have alphanumeric characters (because is a PIN).

If i would like to get the numeric value of the ID of that user, i should connect to the database first... and i want to avoid that.

How could i transform "BEA41341" to an integer so i can apply your solution?

Mahabub

6:40 am on Dec 17, 2008 (gmt 0)

10+ Year Member



Dear asantos,

You can convert the alphabetic character into a predefined value. Like
A=1, B=2, C=3 , D=4, E=5, ........ so on

Then you can easily convert BEA41341 into 25141341. May be there is another good solutions. But right now i think that when i will get a new one I must let you know.

Thanks
Mahabub

vincevincevince

6:49 am on Dec 17, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I am going the other way here; profile images are a good candidate for storage in the database as BLOB. Ask yourself if you would be happy with having all the user data, but losing all the images? I am assuming that would not be tolerable; and if you agree then it's a good idea to unite the data and the images - by keeping them together in the database.

LifeinAsia

5:17 pm on Dec 17, 2008 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



Ask yourself if you would be happy with having all the user data, but losing all the images?

If you're doing regular backups (of both the data and images), that should be a non-issue. Personally, if it is a choice between data and no images or no data with no images, I'd definitely opt for the data w/o images.

We have a very DB-intensive site. So we prefer to let the OS handle image serving/backing up. Also, for a restore, I'd rather have a quick restore of all the data instead of a longer period to restore the data + images together.

As somewhat of a compromise, I guess you could store data in one database and images in another.

[edited by: LifeinAsia at 5:20 pm (utc) on Dec. 17, 2008]

asantos

10:05 pm on Dec 17, 2008 (gmt 0)

10+ Year Member



@Mahabub
That wouldnt work. Because if you have this two PINs:

A123
1123

They would be the same once i translate them to integer values. Im still searching for other alternatives.

janharders

11:06 pm on Dec 17, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



are the PINs fixed length? in that case: just substitute A with 11, B with 12, so you'd be sure to get different IDs, e.g. in case of A123, you'd end up with 11123.
if it's not fixed: is there any hard form for the PINs? like, do they always have to contain letters or may users chooseetc

LifeinAsia

11:18 pm on Dec 17, 2008 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



Why not just go by the initial character of the ID? Then you have 36 subdirectories: 0-9 and A-Z.

milocold

12:05 pm on Dec 18, 2008 (gmt 0)

10+ Year Member



I agree with vince^3 on avatars being a good blob candidate.

My reasoning for this:

-> Small files, shouldn't take up too much DB space
-> I don't wanna back up 50k+ avatar files regularly...*shivers*
-> User maintenance is made pretty simple.
1) User opts out, delete his record. No need to mess with deleting a file.
2) User updates avatar, no need to find the previous, delete it, and upload the new one...just simply update a field. (I guess this one really depends on how you plan on handling/naming your avatar files. Because copy() could be used to just overwrite whatever was associated with account X.)

Now, I wouldn't go hog wild and store big image files in my DB, but a 50x50 pic seemed alright.

-M. Cold

vincevincevince

12:56 pm on Dec 18, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Another point - you can use the DATA URI scheme to deliver the images to most modern browsers (basically all apart from IE6 and IE7). This means no extra HTTP request - just throw out the image inline.

janharders

3:37 pm on Dec 18, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



basically all apart from IE6 and IE7

that's like saying "all but the majority" ;)

every advantage is also a disadvantage in that decision: mysql-dumps take longer and are bigger, unless you want to rely on doing incremental dumps, but the lazy folks like me just put a complete dump into the backup and are happy. files are easy to be backed up with rsync or whatever backup solution you use for your regular files.

vincevincevince

6:06 pm on Dec 18, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



that's like saying "all but the majority"

Always build for two or three years ahead. Support today's browsers only grudgingly. IE8 has great data uri support, even in beta.

asantos

6:51 pm on Dec 18, 2008 (gmt 0)

10+ Year Member



Well, the user cant choose, the PIN depends on a serial key from a PDA :s

The images will be saved as JPEGs at 480x320... multiply that by 50k times... and the DB will be too big.

I think i'll put them on directories and i will follow janharder's recommendation of placing 1000 pictures per directory by using. I did tweak his code a little, and i got this:

$id = $_GET['id'];
$dir = str_pad(($id - ($id % 1000))/1000,4,'0',STR_PAD_LEFT);

That way:
* user IDs 1 through 999 will be saved on directory '0000'
* user IDs 1000 through 1999 will be saved on directory '0001'
and so on...

Of course i wont be able to use the PIN itself... i will have to use the ID associated to that PIN, and save the images as %id%.jpg

milocold

11:42 pm on Dec 18, 2008 (gmt 0)

10+ Year Member



Avatars of 480x320!?!

lol. At that size I think you're outside the avatar ballpark. =)

-M. Cold

asantos

4:40 pm on Dec 19, 2008 (gmt 0)

10+ Year Member



sorry, i meant profile pictures ;)