【问题标题】:Storing expirable credits in database?在数据库中存储过期信用?
【发布时间】:2015-05-06 02:35:56
【问题描述】:

在用户表中使用额外的列很容易存储用户信用,例如user_credits,现在是一个额外的要求

  • 对于添加到 user_credits 列的每个积分,如果未使用,它将在一年后自动过期。

我当然需要一个额外的表来存储过期信息,例如

[table credits_history]
user_id
credits
used
created_at

所以,在消费积分时,我需要

  • 检查user_credits是否足够消费
  • 循环所有credits_history表中used = 0 AND now - created_at < 1yr的用户信用,并设置used to 1
  • 更新user_credits

最后,我需要通过查看created_at 来设置每日 cron 作业以更新 user_credits

上述方法合理吗?或者任何标准的方式来处理上述要求?

【问题讨论】:

    标签: mysql sql database database-design database-schema


    【解决方案1】:

    不要存储您可以计算的东西,除非计算成本太高。假设credits_history 中每个用户的行数不太高,您可以构建查询以检查可用积分的总和:

    SELECT SUM(credits-consumed) -- see more about "consumed" below
    FROM credits_history
    WHERE user_id=?
      AND created_at >= DATE_SUB(NOW(),INTERVAL 1 YEAR)
    

    这种方法的另一个好处是您不再需要 cron 作业来维护 user_credits

    消耗积分变得有点棘手:您需要添加一列来显示已使用的积分部分。这里有一个例子来说明这一点。假设用户在他的历史记录中添加了这些信用:

    created_on credits consumed
    ---------- ------- --------
    05/06/2014   50        0
    07/12/2014   70        0
    12/01/2014   40        0
    

    如果您运行上面的查询,您将得到 160 的总和。

    现在他想消耗 90 积分。您的代码应查询所有符合条件的信用记录,从最旧到最新对它们进行排序,并根据需要使用尽可能多的信用来支付所需的金额(即 90)

    created_on credits consumed
    ---------- ------- --------
    05/06/2014   50       50
    07/12/2014   70       40
    12/01/2014   40        0
    

    现在上面的查询将得到 70 的总和。

    【讨论】:

      【解决方案2】:

      不,我不认为这是一种正常的方法。通常你会有一个像 user_credits 这样的表,每个用户可以有多行,每个这样的行都有剩余信用和到期日期(我认为我更喜欢到期日期而不是 created_at,因为你只计算一次)。但是你会有一个交易表,其中列出了贷方/借方(正/负贷方)。购买积分将创建添加该数量积分的交易。使用积分将创建一个被扣除的积分金额的交易。即将到期的积分只是另一笔被扣除的积分交易。每笔交易还会更新 user_credits 中的剩余信用。 唯一烦人的是,要计算用户的当前信用,您必须转到 user_credits 并将该用户的所有行加起来。有些人可能会跟踪主用户表中的另一个值以绕过它。

      可以通过 cron 作业来整理该表来完成过期信用。虽然如果你想小气一点,你也可以在交易时检查到期日期,以确保没有人在 cron 作业之前偷偷溜进来。

      【讨论】:

        【解决方案3】:

        我会这样做

        表:USER (id,name,address,phone,etc)
        表:CREDIT_TYPE(id,description, expiration_policy, etc)
        表:USER_CREDIT(user_id, credit_type_id, activation_date, expiration_date)

        • 用户有零个或多个积分
        • 每个信用都有某种到期政策、规则等
        • 如果 CURRENT_DATE > expiration_date,则信用过期

        到期日期是根据 credit_type 上规定的政策立即设置的

        这行得通吗?

        【讨论】:

          猜你喜欢
          • 2018-04-21
          • 1970-01-01
          • 2018-01-05
          • 2015-10-08
          • 2015-04-26
          • 2010-12-05
          • 2013-11-28
          • 1970-01-01
          • 2013-02-19
          相关资源
          最近更新 更多