Image path in database vs intelligent folder structure - database

Assuming I want to safe one profile picture for each user of my system.
Is it better to save the path to this image in my database or to rely on a intelligent folder structure like
/images/users/user1.png
and access the image directly?
What if I have more then one picture per user? Would this be a good practice?
/images/user1/pic1.png
So basically my question is, why would you save the picture's path and waste space when you already know where the pictures are without any db queries?
This is just a general question apart from any technologies.

It's always better to assume that each user will have more than one picture, even if you're absolutely sure of otherwise now.. Two ways to go about it:
Each user will have a folder for all their pictures. /path/user1/img1.jpg , /path/user1/im2.gif
All the pictures will be in the same folder, but the username will be a prefix of the filename /path/user_pics/user1_img1.jpg , /path/user_pics/user2_img3.gif
Personally, I prefer the former.
In most cases, you won't need to store the full path of the picture in a database.. Storing the image content-type (which determines its extension) and the filename will generally be enough. That gives you more freedom as to which machine is serving the image itself.

Related

Picture on phpmyadmin

I would like to put photos in my phpmyadmin database but I can't find the solution that allows me to do so. I made an image array with a varchar but I can't find the path that allows to put an image. I thank you in advance for helping a young beginner ❤️
The best solution is to store the image as a file on disk and put the path to the file in the database (as a varchar or some other text type), then your application references the file instead of loading the BLOB data directly from the database. There are performance reasons that are well documented elsewhere that explain the intricate details better than I can, but basically the database slows and the amount of disk space it takes up expands as you store the images in the database.
If you decide to defy that advice and store the image directly in the database, you shouldn't be using phpMyAdmin as your main interface. Don't get me wrong, it's fully capable of uploading the image, but presumably you'll have some custom application interface that you should be using instead that also does application-level logic. But that's not what you asked, so to do this in phpMyAdmin, there should be a "Browse" button near the field on the phpMyAdmin Insert page. This requires your column be some appropriate sort of binary such as BLOB.

Database Tables for files in filesystem

i needed to save images to my back-end, and finally went with storing them in the file system instead of in the database as blobs. So now i have a different issue, i want to make my database as optimized as possible. Here are my needs, and my approaches:
I have these entities:
User
Image
In my file system, i can store the images in directories named after the user id. So basically:
16
asd.jpg
blaBla.jpg
Would represent the images about the user with id 16.
Now, i know i will have a lot of directories and a lot of images, and i know that storing their paths in a database would be better than querying the file system. (or would the OS know the locations of all the directories, making these tables not needed?)However i was wondering should i make a table such as (userId,imagePath), connecting every image to a userid, or (userId,directoryPath), connecting every-user with the path to his directory, then use something like Files.walk(directoryPath) to list all of the paths of the images inside that directory. What would be a better approach, or is this way to opinion-based ? A completely different approach or any tips would also be appreciated.

Server backend: how to generate file paths for uploaded files?

I am trying to create a site where users can upload images, videos and other types of files.
I did some research and people seem to suggest that saving the files as BLOB in database is a Bad idea; instead, save the file paths in database.
My questions are, if I save the file paths in a database:
1. How do I generate the file names?
I thought about computing the MD5 value of the file name, but what if two files have the same name? Adding the username and time-stamp etc. to file name? Does it even make sense?
2. What is the best directory structure?
If a user uploads images at 12/17/2013, 12/18/2018, can I just put it in user_ABC/images/, then create time-stamped sub-directories 20131217, 20131218 etc. ? What is the best structure for all these stuff?
3. How do all these come together?
It seems like maintaining this system is such a pain, because the file system manipulation scripts are tightly coupled with the database operations(may also need the worry about database transactions? Say in one transaction I updated the database but failed to modify the file system so I need to roll back my database?).
And I think this system doesn't scale (what if my machine runs out of hard disk so I need to upload the files to a second machine? What if my contents are on a cluster?)
I think my real question is:
4. Is there any existing framework/design pattern/db that handles this problem?
What is the standard way of handling this kind of problems?
Thanks in advance for your answers.
I've actually asked this same question when I was designing a social website for food chefs. I decided to store the url of the image in a MySQL database along with recipe. If you plan on storing multiple images for one recipe, in my example, maybe having a comma separated value would work. When the recipe loaded on the page, I would fetch the image associated with that recipe onto the screen.
Since it was a hackathon and wasn't meant for production purposes, I didn't encode the file name into something unique. However, if I were developing for productional purposes, I would append the time-stamp to the media file name when storing it into the server and database/backend.
I believe what I've proposed is the best data structure of handling this scenario. Storing the image onto the server is not only faster, but it should also take less space. I have found that when converting a standard jpg file of reasonable resolution to base64 encoding, the encoded text file representation took 30% more space. There is also the time of encoding the file and decoding the file for storage and resolving when using some BLOB type of data format instead of straight up storing the file on the server.
Using some sort of backend server scripting like PHP, you'll be able to do some pretty neat stuff with the information you have available. Fetch the result from the database, and load it in from the page using HTML.
As far as I know, there isn't a standard way of fetching media from a database yet. Perhaps there will be one day.
There is not standard way to do that, it is different to the different application. The idea is you need generate a different Path+FileName for every upload, here is a way:
HashId = sha1(microsecond + random(1,1000000));
Path = /[user_id]/[HashId{0,2}]/[HashId{-2}];
FileName = HashId

How should I store per-user data in WinForms?

In my WinForms app, I have a few textboxes that the user typed some data into. I want to store the data, but I don't want to use a database. In my stone-age C++ days, I'd just use a .ini. Somehow, app.config doesn't seem like the right place to store this data, though.
What are my other options?
I would say the .config file is the right place. Just be sure to use the User scoped area of the Settings.settings file rather than the Application scope.
This works well for simple data types and when you have fixed values that will need to be saved because you need to define what variables you want to store at design time. So if your textboxes are dynamically created and you don't know many values you need to store it is not very useful.
Using IsolatedStorage might be another good option. You can create your own file in any format you want (keeping any values you need) and store it to the local machine in "IsolatedStorage".
You can create a folder somewhere on the disk and simply write a file in any suitable format (XML, plain text, your choice). You could for instance do this under the path pointed out by Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) or Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData).
I would look into isolated storage. It is easy to set up per-user. And since it requires only partial trust, it will work for any deployment scenario.
Check this introduction.
Depending on how many variables/data you're looking to save the app.config/settings file can be the ideal place.
Check out the Settings Tab in the Project properties and note that you can set both Application settings and User settings. Application settings affect the entire application. User settings are stored per user.
The section of the app.config that contains user settings will be saved to the user directory when they are saved and reincorporated when they restart the app.
Check this url for an introduction to Application/user settings on MSDN and also this SO url for a similiar question.:
You could also look into storing your familiar old .ini files in a per user .ini by checking out the Special Folders enum as per this url.
I believe the proper place to store user settings in WinForms 2.0 would be in the settings file (not the config file). Here's a quick article for explanation.
Create a .config or other data file (e.g. xml) in the application data for the specific user.
use system.environment.specialfolder to get the ApplicationData folder, add a subfolder with your company name, within this a subfolder with your application name, within this your data file for this specific user. Thus,
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\YourCompany\\YourApplication\\YourData.config"

When storing Images in the File System, Use relative paths or absolute paths?

I am working on a web app and I decided (after reading many post on SO) to store the actual images in the file system and to store the metadata in the DB.
Should I store a relative path or an absolute path.
I can think of some advantages for each of the choices.
Absolute:
Pros:
It is obvious where the file is even to other apps reading the DB
Can put the photos anywhere on the drive (would require an handler)
Cons:
Need to convert the absoulte path to a relative path for use in the site or create a handler
If I migrate to another server I may have to change all the paths
Relative:
Pros:
Simply add the link to the html and it works
Cons:
If I change the app root I have to move the pictures or change all the paths
Have to put the pictures in a public directory (Or I gain nothing over the absolute path)
Ok these are some of things going on in my head right now.
I can't decide.
I would store a relative path in the database. This gives you the greatest flexibility. Loading images is a simple matter of prepending an "IMAGE_ROOT" variable (which should probably be configurable) to get the filesystem path. This is important because you might want to move where the images are stored (put them on a faster drive, for example). Then it is simply changing the configurable IMAGE_ROOT.
When putting a reference to the image into a page, I'd put the full URL. Again, this is simply adding a URL_ROOT to the relative path. This gives you the advantage of being able to easily switch servers if you find load requires dedicated servers for serving images.
If you are interested in the portability of the info in your database, just store a base path in the database as well. That way, when you move the files, all you need to do is modify the base path that you've stored in the DB. This information should be stored separately from the file paths. Storing such information in the same row would create a lot of unnecessary duplication.
I prefer to store them as relative paths so the application is not dependent on its location. With ASP.NET there is the "~" to automatically signify the application root, you could do the same and then simply replace it with a constant when using it, that way you do not have to worry if you change the app root.
If you're using SQL Server 2008, you can solve this problem neatly with the new FILESTREAM data type.
I concur. Storing relative paths means less info in the db and if you store a base path somewhere, you only need to modify it once. You then build your full urls by adding the shorter link from the database to your basepath.

Resources