store multiple sizes of one image, filesystem or database approach
I know this question has been ask many times, but mine is more about storing an image that has multiple sizes.
I've already decided that my images will be store in the file system. So, that's checked!
Every master image uploaded via input type="file" will be given an unique id using the unid function in php: uniqid('fc_', true)
Now, my dilemma is how to store the different sizes (or children) of the master image.
As per now, the master image contains a record in the database (id, title, description, type, filename) and it is store in the file system. The different sizes of the master image are move to the file system directly (no record in the database) and they named using the uniqid of the master image + some added text. So:
Master: fc_345679849.89675849.jpg
size (30px) : fc_345679849.89675849_tiny.jpg
size (50px) : fc_345679849.89675849_small.jpg
size (100px) : fc_345679849.89675849_medium.jpg
size (500px) : fc_345679849.89675849_large.jpg
When I started to look more into this system and how others do it, I became more doubtful if it was the correct approach.
The other approach I was thinking of, was the one that stores every image (a reference to the image, not the actual image), including the ones with different sizes in the database. They all will have a primary key and, if it applies, a reference to the master image, like so:
id, ..., filename, master_imageid
_____________________________
1, ... , 34.jpg, NULL
2, ... , 23.jpg, 1
3, ... , 45.jpg, 1
4, ... , 12.jpg, 1
5, ... , 8.jpg, 1
So image 1 is the master, and the rest (different sizes) are children of the master... that is image 2, 3, 4, 5
So, system#1: one record for the master, the children have no db record and have a convenient text to there respecti开发者_开发技巧ve filename to link them to the master.
System#2: one record for the master, and one record for each children. No need to add a convenient text to the filename of the children, coz the column master_imageid will automatically link them to the master.
Any thought on what is the best solution?
Thanks in advance
I would suggest the filesystem based approach. This way, you are able to get the filename for various sizes using simple string manipulation; the database-centric approach, while elegant, adds an extra layer of indirection -- assuming no database caching, you're running 1 HDD read to get the filename + 1 HDD read to get the actual image data vs. 1 in-RAM concatenation to get the filename + 1 HDD read to get the actual image data. This, coupled with the inherent latency databases tend to introduce, doesn't paint that pretty a painting!
That said, there are a few advantages using a database might offer. If you do not want your users to cleverly affix "_small" to whatever file to get their hands on a tinier version, no doubt using databases might be a somewhat more attractive approach. But even so, there are better alternatives, especially in the absence of caching.
If users getting access to files by simple URL manipulation is indeed an issue, I think you might still save time if you, for instance, concatenated the unique image ID with a resolution specifier, and hashed the filename using a sufficiently inexpensive yet collision-proof over small ranges hashing algorithm (MD5 comes to mind) to generate the filename.
Do note that all of these approaches are trivially defeated on the performance ground the moment any degree of caching joins the fray. Ideally, if it's undesirable to have the URLs manipulable, you'd want to precompute unique filenames and store them in a database, and use memcached/redis/whatever to perform lookups at runtime.
Why create a uniqueid, when each database record already has a unique id field?
image table
id, created_by, etc
so if the records id is 234, the filename would be 234.jpg or whatever. if you use a uniqueid() as the filename, make sure to check that the filename does not already exist. if two files were somehow created during the same microsecond, they could have the same uniqueid.
also, what is wrong with attaching text for different sizes? seems like the best way to me.
234_thumb.jpg
234_small.jpg
234_large.jpg
精彩评论