views:

156

answers:

3

The platform isn't really as important as the theory. For the record, it is ASP.NET (C# on 3.5 SP1), SQL Server 2005. For the sake of argument, I have unlimited space (filesystem and database) and unlimited bandwidth.

I am working on a project that would allow multiple users to upload their own images which could be managed by that user and viewed by all users. I am trying to determine what the best storage mechanism is. My line of thought is that I would want to avoid storing them in the database directly, although I could see storing information about the images.

What I am seeing is that the user would upload the image. The server would create a unique name for the image, store it to the filesystem, and store the relational data about that image in the database (i.e. when it was uploaded, the association to the user, reference to a caption, etc.). Having these on disk is one step towards being able to move to a CDN in the future.

Has anyone used an approach like this or could recommend a different approach? Should there be some sort of a folder structure, such as a folder for each user to help file access times?

Any feedback would be appreciated!

+1  A: 

Something I think you should consider is referencing PresentationBase.dll, it will give you access to the Windows Imaging Component (WIC) wrapped by Windows Presentation Foundation. Even if this is a ASP.NET project you can rely on these classes for image encoding and decoding. These classes worth with binary data or streams and can decode and encode several popular image formats and generate thumbnails on the fly off a high resolution store through different decoding and encoding, height and width.

The classes are located in the System.Windows.Media.Imaging namespace and derive from BitmapEncoder or BitmapDecoder. There's also several other third-party implementations that you can benefit from if you use these classes.

John Leidegren
Thank you, John! I haven't done much with WPF yet, so that definitely sounds like a good way to get my feet wet. :-)
joseph.ferris
+1  A: 

I think you already are on the right track as far as the recommended practice is concerned: Store data about the uploaded file in the database such as the filesystem location, filename, attributes, caption etc, but store the actual file in a designated folder specified explicitly for this purpose.

This approach also allows you to check uploaded files for format restrictions and scan it for viruses before finalizing the upload process.

Storing binary content such as images in the database is definitely not recommended and this opinion seems to be pretty widespread.

Cerebrus
Thank you. I used to store images in the database because of the "everyone else is doing it" mentality, but it just does not make sense anymore. I hadn't even thought about virus scanning, yet, either.
joseph.ferris
Most welcome! Glad I could assist. ;-)
Cerebrus
+3  A: 

I agree that storing images/files on the filesystem instead of a database is a good approach.

Regarding file access times you might want to check the filesystem you use on how it behaves if a directory contains a lot of files. Some filesystems might degrade in performance if this is a huge list. If so you might want to create some folder structure, e.g. from 00-FF and this maybe on several levels depending on the amount of files you expect. You could then e.g. use the MD5 hash of some field (like filename) to sort this into the right directory (e.g. hash FABE063E... goes into FA/BE/filename).

If you don't want filenames to be guessable in order to restrict access you can also use some hash or even random string as the filename. That way only those users who know the filename (e.g. by you providing the link to it) can access this file. This might also be important if you want to move to a CDN where you eventually cannot check permissions yourself.

(If permissions are not important and OTOH want guessable filenames you apparently go the other way and maybe use usernames as a folder structure etc.)

MrTopf
That is definitely something that should be taken into account. I am not as worried about protecting access, since they are intended to be shared amongst users of the application. I probably have to mock up some folder structures and perform some access testing to get real measurements of time.
joseph.ferris
That is a good answer! You've touched upon some concepts that seem to get addressed only late in the development cycle. +1
Cerebrus
Thanks :-) I am trying to think of such things in advance even if I don't need it later on. But better to enable such things early on and not be screwed later.
MrTopf