在您的情况下,您可以有这样的表格:
pass: (id, user_id, start_time, end_time, credit)
每天,您都可以在任何过期的通行证上刷新未使用的信用:
update user join
(select user_id, sum(credit) as credit from pass
group by user_id where end_time <= now() and not flushed) b
set user.credit = max(user.credit - b.credit, 0)
where user.user_id = b.user_id
update pass set flushed = 1 where end_time <= now() and not flushed
通过使用 end_time <= now() 您可以确保仅在到期日期过后才重置信用。由于您记得哪些通道被刷新,您可以随意运行它,并且错过一天不是问题(它将在下一次运行时检测到)。
这实际上是预付费电话卡的工作方式 - 您有一定数量的分钟数,有效期为 X(30/60/90 天),最后会重置分钟数。
顺便说一句,您可以使用易于使用的订阅管理系统(如recurly或chargify )来简化所有这些工作。