views:

39

answers:

2

I've got an ads table, with ads which can be promoted in two ways. They can be promoted in search results, so they come before the others, or they can be promoted to the front page, where a random selection of a few promoted ads are displayed. They are to be promoted for a certain time period.

I'm not sure how to best do this.

Another table for these promoted ads, and should I have a cron job to delete them once they expire, or... how?

A: 

The best thing would be to have a second table, with a foreign key to the ads table, a column for the promotion rank (if desired), a column for the expiration date, and a column showing whether it's front page, search, or anything else you want to add later. (ie: 1 for search, 2 for front page, or 'search' and 'front_page' respectively)

When you select an ad to promote, you select from the AD_PROMOTION table and join it to the ADS table. Then, rather than using a cronjob to kill it when the expiration date has gone, you just demote or remove it when it gets selected.

while (ad != null) {
    ad = getRandomAd()
    if (ad.expires < now()) {
        demote(ad);
        ad = null; // Make sure you get another one
    }
}

Of course, you'd need something in place to make sure you wind up with an ad at some point, since you may not have any promoted ones.

ADS
AD_ID    INFORMATION
-----    -----------
1        'Max Power'
2        'Min Power'
3        'Homer Simpson'

AD_PROMOTION
AD_ID    LEVEL    EXPIRATION_DATE    PLACE
-----    -----    ---------------    -----
2        2        2010-02-18         'search'
3        3        2010-03-01         'front_page'
3        2        2010-04-01         'search'
Slokun
but the ad can be promoted to the front page and in the search results both at once
Sorry, missed that part. Edited my answer to take this into account.
Slokun
+1  A: 

I think there are two concepts here, the ad and the publication.

Talking specifically about database design, it depends on how much information you want to add to the publication.

If it's just the type, you can do with a (possibly numeric) field in the same table.

If you need to add more publication specific info, you will be better off with a new table for these, this opens some interesting design questions like if an ad can have only one or many different publications (appear first and also include it in a mail newsletter for example).

Pablo Fernandez
yes, it can be promoted once in each way
The relation is 1 to 1?
Pablo Fernandez
no, one to many. the ad can be promoted at once both in the search results and on to the front page
Ok so clearly you need two tables. I think the odds of having a third kind of promotion in the near future are pretty high. Database design is one of the paces where you don't wanna go YAGNI
Pablo Fernandez
yes, i suppose. so how best to deal with expired promotions then?
You might never delete the promotions but have a __expires__ field, and when you query for the __promotions__ you do something like `Select * from promotions where expires > date.now()` or something (I'm pretty bad at sql but you hopefully understand what I mean)
Pablo Fernandez
With that strategy you could keep a historical record of all promotions, so that you can know which are the ads more promoted (better clients).
Pablo Fernandez
zero votes and accepted answer! Weird!
Pablo Fernandez
i cant upvote yet. not enough reputation