Reputation:
Quick question:
We want to be able to store a user avatar image for our chat users, so that everyone who is logged into the application can see that image in regards to the user. This is a C# winforms chat IRC application, which authenticates against a DB for the user, before handling the IRC commands.
Essentially, we want to be able to query the image for the user from a BLOB in the database, and assign that image to a control. This will allow us to have everyone upload an avatar (if they wish), and everyone see that as well as their username in the user cards we are creating.
Is it best to store those images in the sql database? I figure it wouldn't be an issue considering that they would be relatively small images (less than 64k), and are only pulled and transmitted when a user is requested from the DB.
Question is, is it the best method to do that? And, how could we do that if we were using the mySqlConnector. Is it as simple as
Select * from Images Where Username='BLAH'
and then just streaming that data as an image stream to the picture box in C#?
Upvotes: 0
Views: 584
Reputation: 76723
Best practise
1- Never do select *
; that's an anti-pattern.
select * selects way too much, only select the field(s) that you need.
SELECT field1 [,field2][,field....] FROM images WHERE
2- username
cannot be a field in table images
; that violates 1NF.
Put users in a separate table:
table user
id unsigned integer not null primary key auto_increment,
-- id is a redundant key to speed up joins.
name varchar(255),
other_fields.....,
unique index ui_name (name) -- << make sure user.name is unique.
table image
id unsigned integer not null primary key auto_increment,
user_id unsigned integer not null,
image_blob blob,
foreign key fk_user_id (user_id) references user(id) on delete cascade on update cascade,
.....
3- If you match on username
, make sure you have a unique index
on that field so no duplicate usernames can exist.
See the table definition for user
above.
Is it best to store those images in the sql database?
It is best from a consistency point of view, because the images will fall under the ACID regime enforced by the transactions in InnoDB.
If you store the images in the filesystem, it is hard to keep the filesystem synced with the DB (if a transaction fails, or a file gets deleted or overwritten the DB and filesystem are out of sync).
Futhermore, having the application write to the filesystem as well as the DB opens up an extra security problem, which does not exist if the app only communicates with the DB.
From a performance point of view it can be faster to write the image to the filesystem.
I would recommend to write to the DB, but to keep open the option to write to the filesystem if and when slowness occurs (but not before).
Is it as simple as
SELECT image_blob from Images i
INNER JOIN user u ON (u.id = i.user_id) WHERE u.name = :userparam
Yes it's that simple.
Upvotes: 1
Reputation: 11924
I think Storing the Image in the database is the best idea, it may be a little slower but it would allow you to update the image transactionally and allow simpliler scalability/high availablilty/security/backups
You are correct you simply select the blob and dump it into a byte array, see: add and retriving image from access database in C#
Upvotes: 0