【问题标题】:Money expiration tracking资金到期跟踪
【发布时间】:2016-08-19 07:25:20
【问题描述】:

我目前正在处理货币到期跟踪问题(最初它不是货币,但我已将其用作更方便的示例)。

用户可以出于某种神秘原因从平台赚钱,然后将其用于购买东西(产品、礼物等)。

我正在寻找一种算法(SQL 查询最佳情况)来查找用户余额的当前余额。

花钱和赚钱的事件存储在不同的数据库 (MySQL) 表中(比如user_earneduser_spent)。所以在正常情况下,我会简单地从user_earned 中计算用户总数并减去花费的金额(user_spent 的总数)。

但是!有一个条件,即用户赚取的钱将在 2 年内到期,如果不使用的话。 这意味着,如果用户没有使用他的钱或只使用了其中的一部分,它们就会过期。如果用户使用他的钱,它们是从最旧的未过期的钱记录中使用的,因此余额(奖金)可以按用户的利益计算。

为了更好地理解案例,以下是 5 个带有事件的场景:

两个表(user_earneduser_spent)都有用于日期跟踪的时间戳

【问题讨论】:

  • 这可能是最好在应用程序代码中完成的任务。
  • 目前,我已经实现了一个服务,它通过简单地构建一个事件列表(接收、使用、到期)并逐个运行它们来计算余额。它可以工作,但如果我需要在 SQL 查询中进行平衡以使用户获得正余额,我必须在将这个值非规范化到数据库之前。

标签: mysql sql database database-design currency


【解决方案1】:

我在我的一个项目中做了类似的事情。

看起来您需要一个带有列的附加表 spends_covering spend_id, earhed_id, sum

因此,对于每条spends 记录,您需要在spends_covering 中插入一行或多行以标记“已使用”资金。

那么余额将只是日期少于 2 年的未使用的总和。

select sum(sub.earned_sum-sub.spent_sum) as balance
from
    (select e.sum as earned_sum, sum(sc.sum) as spent_sum 
    from earned e
         left join spends_covering sc on e.earhed_id=sc.earhed_id
    where e.date BETWEEN ...
    group by e.earhed_id
    having earned_sum > spent_sum) sub

【讨论】:

    【解决方案2】:

    拥有两张表可能是值得的——一张(或更多)包含所有历史详细信息,一张仅包含每个“用户”的当前余额。请务必使用事务来保持两者同步。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多