Scenario: Each user add funds to his account, for example 100 USD, and he defines that the system (our website) could spend up-to 10 USD per day for showing his ads in the website. each time his ad is shown in or website, it's gonna cost him 1 USD.
P.S: we're not inserting a record into the database every time his ad is shown, we just deduct
the amount for showing his ad (1 USD
) from his whole budget.
because we're showing too many ads, it's not possible to insert a record for each ad show into the database.
I have 2 columns in users table, whole_budget
and daily_budget
, so for the above user whole_budget
is 100
and daily_budget
is 10
.
in the above scenario, how can we manage daily budget
? so when an ad is shown, how we're gonna deduct 1 USD from his account?
how can we know if he has left daily budget? so we can decide to show his ad for the rest of the day or not.
I would appreciate your help
EDIT —————
This could be simply achieved by having a table called shown_ads
, and every time we show an ad, we insert a record in this table with the respected DATE() so we can later on calculate the amount of his budget already spent today. but imagine we're showing 1M
ads each day, so what I believe is that it's not good to insert 1M records every day! It's just a case-study, I want to know how would you implement this.
Best Answer
The easiest solution (probably) would be:
Have one table for the whole budget for each campaign (let users have more than one ad at a time :-):
Have a second table for the budget of just today
Every day, at 00:00, perform the following operations:
spent_budget
(original_daily_budget - available_daily_budget
) from thebudget
DELETE
everything fromtodays_budget
INSERT
new rows totodays_budget
, with both original_daily and available_daily budget equal to the min of (daily_budget_limit, available_budget)This can be done with the following queries:
Subtract remaining from yesterday
Clear out everything from todays_budget
And fill it up again
And very time you show an ad: Subtract one from
available_daily_budget
Notes
SET ISOLATION LEVEL SERIALIZABLE
; to avoid concurrency issues. If any of the check constraints fails, the whole transaction will be aborted and you'll have to retry it as a whole.