实现订阅模型的算法 - 如何确定用户的当前订阅?

时间:2017-02-02 05:43:02

标签: database algorithm database-design payment

我有用户,订阅和付款。 订阅可持续一周,一个月和六个月。它中有“持续时间”列。

订阅表中只有3条记录:

id, name, duration, type:

1, Subscription1, 1, week
2, Subscription2, 1, month
3, Subscription3, 6, month

用户可以一次购买一些订阅,这样一旦在一周或一个月后使用了一次,等等,下一个 - 第二个最近付费的订阅变为活动状态。因此,如果用户购买了3个订阅,则第一个订阅变为活动而另外两个等待。

付款可以有不同的状态,例如ok,failed,pending。

我正在试图找出如何确定当前用户的订阅,而无需创建新表UserCurrentSubscription以避免复杂性和冗余。

我该怎么做?如果我使用状态为“ok”的最新付款,它仍然可能不会让我推断用户当前的订阅,因为如果用户购买了几个订阅会怎么样?

我只需要一个算法。

3 个答案:

答案 0 :(得分:1)

(这应该是评论,但我缺乏声誉。)

如果没有subscription_start_time的字段,我不知道这个问题是如何回答的,因为用户购买月订阅然后一周订阅的情况与用户购买周订阅然后是一个月的订阅。

答案 1 :(得分:0)

在评论中,您已澄清在Subscription表中有一个名为added_at的列,我认为该列包含一个日期。我猜这里也是用户的外键。假设第一个订阅从added_at日期开始,您可以使用duration和type列来查找用户最早订阅的结束日期(您必须决定如何订购订阅 - 可能通过增量id列)。然后,您可以假定下一个订阅的开始日期是第一个订阅的结束日期之后的第二天,依此类推。

每次需要查询此表时,这都是在SQL或前端代码中执行的一个令人不愉快的逻辑。如果可能,我会改为将Subscription表更改为具有start_date和end_date列,并在订阅插入表时执行此逻辑。如果一次插入一个订阅而不是批量订阅,这也可以节省您需要执行任何先前的行/下一行类型逻辑 - 您只需查找该用户的现有订阅的最大结束日期,添加一天,现在您有了要插入的订阅的开始日期。如果您要为特定用户插入第一个订阅,您只需将added_at的值插入start_date。

对于Subscription中的每一行,如果你有start_date和end_date,那么检查哪一个订阅在任何一天都是有效的。

答案 2 :(得分:0)

我认为您最好的选择是向用户添加一个列,标题为subscription_end_date,以null或0开头(取决于您的首选格式),并且每次更新到新的订阅日期结束时用户购买订阅并且付款已完成(使用将付款状态更新为ok的相同方法):如果新订阅的日期超过了今天,则会将新订阅的长度添加到此字段。否则它会将其更新为今天+新购买的订阅的长度。

如果您不想添加任何字段,您可以使用以下内容每次重新计算它,但这是非常昂贵的,我建议反对它(我假设在下面付款已经在其中购买订阅的列,可能是通过拥有一个列来保存适当的订阅ID):

  1. 定义一个Date变量(称为sub_end_date),该变量将保留算法结束时最后一次订阅的最后一天。使用比您开始收款时更早的日期(例如1970年1月1日)实例化它。
  2. 完成该用户的所有ok状态付款,按其日期排序,从最早开始。对于他们每个人:

    2.1。如果付款日期在sub_end_date中的日期之前,则将支付的订阅长度添加到sub_end_date,并使用该总和中的新日期更新sub_end_date。

    2.2。 else(保存在sub_end_date中的日期在付款日期之前)将订阅的长度添加到付款日期,并用该金额更新sub_end_date。

  3. 当您完成所有用户的付款后 - 如果sub_end_date在今天的日期之前,那么用户没有有效的订阅。否则他们会这样做。