I want to create a basic database that handles photos. Also, i want to show a photo of the day to the user.
I´ve created a table called ´photo´ and another table ´photooftheday´, like so
CREATE TABLE `photo` (
`photo_id` SMALLINT(5) UNSIGNED NOT NULL AUTO_INCREMENT,
`title` VARCHAR(100) NOT NULL,
`caption` VARCHAR(255) NOT NULL,
`filename` CHAR(29) NOT NULL,
PRIMARY KEY (`photo_id`)
)
CREATE TABLE `photooftheday` (
`photo_id` SMALLINT(5) UNSIGNED NOT NULL,
`date` DATE NOT NULL
)
I didn't add an auto increment column for the table photooftheday, coz I believe it’s not necessary (maybe I’m wrong).
My question is about the table ´photooftheday´. I don’t know how to handle keys so each day contains a photo that is not already selected in another day. In this case, i’m confused about primary keys, unique keys, keys, foreign keys, column indexes…
Also, if it helps, my query to select the photo of the day is going to use the date column, like:
$todays_date = date('Y-m-d');
$q = "SELECT p.photo_id, p.title, p.caption, p.filename
FROM photooftheday pd
JOIN photo p ON pd.photo_id = p.photo_id
WHERE DATE(pd.date) = '$todays_date'";
How do i handle the columns in the table photooftheday, so to optimize it?
Thanks
Best Answer
As mdoyle already mentioned, if you really want every image to show up exactly once over all time, you can add a unique index onto
photo_id
. And extracted from the comments you also want to assure that every date exists only once in your table.I would like to mention several other issues.
You might want to use InnoDB as storage engine. This way you can add a foreign key (or foreign index) and make sure that the column
photo_id
ofphotooftheday
contains only valid values from the columnphoto_id
ofphoto
. The database will check if this is true on inserts and updates. You would also want to put a normal index onphotooftheday.date
for faster lookups, but since you want a unique index on this column, you can skip the normal index.The four types of indexes (or keys) are:
date
ordate
andphoto_id
(this is based on what you want...). You might add this index too. If you want to put it ondate
(which seems reasonable from your comments until now), you can skip the unique key I added. The primary key assures that all values are unique, so an additional unique key means only additional overhead.I have added the storage engine definition, the unique indexes and the foreign key to your create table statements:
Your select statement can be improved too. Firstly MySQL provides date functions too, so there is no need to use the php function and insert values into the select statement. You can use the mysql function
NOW()
, which returns the current datetime stamp.The other aspect is a little bit more complicated. You have a
WHERE
clause to find all rows for today, but you apply a function ondate
. This makes it impossible for the database to use your newly created index ondate
. Luckily you do not need to call the function! Yourdate
column is already of the typeDATE
, so basically containsyyyy-mm-dd
. You only need something to compare this value with, which would be the output ofNOW()
.NOW()
returns something likeyyyy-mm-dd hh:ii:ss
(so time too), but you only need the date part. You can extract this with theDATE()
mysql function. Just put the two functions together then. The whole query looks like:and will be executed a lot faster, than the original version.