Mysql – What are the possible considerations and drawbacks of storing binary image data directly in a table

MySQLschema

Although related to this question, I have a slightly different angle to approach this issue from. Here is my situation:

I am writing a web application (either in PHP or Python) that manages addons for a desktop application. Users can browse addons, install them, upload them, etc.

I am planning the schema for the database and found myself with a decision to make:

Is it better to store icons (for the addons) in the table itself or instead store them in the filesystem and simply store a filename in the table?

The icons are small (48×48 or close to that) and likely won't take up more than 5 or 6 KB at the most. Are there any serious drawbacks to storing the image data in the table? Are there other implications that I should be aware of? Will performance be a concern? Will storage be an issue?


Edit: I am currently looking at MyISAM tables in a MySQL database.

Best Answer

You haven't specified the database platform your considering but at this size/scale, it's unlikely to matter.

5kb per record is trivial. 1 million 5kb records is < 5GB, still trivial. 10 million 5kb records... still not something to lose any sleep about.

If we were to get platform specific, a typically exhaustively researched white paper by Paul Randall on SQL Server filestream storage suggests that it outperforms table storage where files are 1MB or greater in size. Below 1MB file sizes, the positives are primarily around filestream bypassing the buffer pool.

The positives for database storage:

  1. Transacted. The binary data is tied to it's metadata, not exposed by a filesystem, safe from accidental deletion.
  2. Reduced backup overhead. 1 million records in a 5GB file vs 1 million 5kb files.
  3. The natural companion to 2), faster restore.

Edit: The negatives (as suggested by Aaron)

  1. Requires programatic access.
  2. Cost of storage. More of an issue if you have to deal with platform restrictions on size e.g. 50GB on Azure.