我正在构建一个限制系统,我们可以使用它来控制用户可以从我们的平台发送多少电子邮件。他们在账单日期每月自动获得 10,000 封电子邮件。他们可以选择在 5,000 个电子邮件包中购买更多。我的想法是将限额贷记和借记添加到表中,然后用于SUM(amount)
计算它们在任何给定时间点的使用情况。
这因一些要求而变得复杂:
- 用户每月自动收到 10,000 封电子邮件。当我们现在计算用户的限额时,它必须从他们的最后一个计费日期开始计算。
- 用户可以购买以增加其限额的插件有一个到期日,如果他们在到期前没有使用插件记入的全部金额,他们将失去剩余金额。
- 插件应该永远存在,直到它们用完,但每月 10,000 点数每个月都会重置。
目前,我为概念证明制作了这个表结构(添加信息列只是为了解释发生了什么):
而这个查询在运行查询时计算用户的电流限制:
SELECT SUM(amount) FROM (
SELECT SUM(credits.amount) as amount
FROM limit_transactions credits
WHERE date >= (
SELECT date FROM limit_transactions WHERE limit_transactions.billing_reset=1 ORDER BY limit_transactions.date DESC -- to start from where the billing cycle reset
)
AND credits.amount > 0 -- to only get credits
AND (credits.expiry IS NULL OR credits.expiry <= NOW()) -- to exclude expired credits
UNION ALL
SELECT SUM(debits.amount) as amount
FROM limit_transactions debits
WHERE date >= (
SELECT date FROM limit_transactions WHERE limit_transactions.billing_reset=1 ORDER BY limit_transactions.date DESC -- to start from where the billing cycle reset
)
AND debits.amount < 0 -- to only get debits
) as amount
我认为这个查询正朝着正确的方向前进,但给出的结果不正确。使用给定的数据集2000
,它应该返回什么时候返回-3000
。这是因为这部分查询:
AND (credits.expiry IS NULL OR credits.expiry <= NOW()) -- to exclude expired credits
完全消除了从整体计算中过期的插件,而不是知道在该插件未过期时发生了哪些借记。
以前有没有人实施过这样的解决方案 - 或者可以提出更好的方法来建模这个数据结构?我可以采用的另一种方法是仅在此表中存储积分,并添加一个used
列来跟踪已使用多少积分。如果用户发送电子邮件,我会增加该used
列。