【问题标题】:Storing complex time intervals in database在数据库中存储复杂的时间间隔
【发布时间】:2016-08-31 13:26:22
【问题描述】:

我正在开发适用于事件的应用程序。 (语言:Python 2.7,RDBMS:PostgreSQL,CSM:Django 1.9.6)。我需要存储有关日历事件的信息。它们具有高度可定制的时间间隔(例如:从 3 月 5 日凌晨 5:00 开始重复 5 次,持续时间为 45 分钟,每周四;或在每个奇数天下午 6:00 重复,持续时间为 1 天 2 小时(从 1 日开始)下午 6:00 到下午 2 点 8:00,然后是下午 3 点 6:00 到下午 4 点 8:00))。

问题是如何存储此类信息,并快速选择实际事件(在当前和未来特定时刻活跃)?

作为一种解决方法:使用 RRule 并定期进行作业来计算第二天每个事件的时间间隔。但是,我认为这是非常耗时的操作,特别是如果服务器上有数千个事件(缓存有帮助,但是当我需要未来特定时刻的活动事件时该怎么办,这是通常的查询)。

【问题讨论】:

  • 每组间隔是否都有合理的终止? PostgreSQL 的最大时间戳是公元 294276 年。
  • “我认为这是非常耗时的操作”——过早的优化是愚蠢的。 “数十亿的事件”你在为地球上的每个人制作日历吗?
  • @MikeSherrill'CatRecall' 感谢您的评论。是的,它有合理的终止。活动的平均时间限制(第一次重复的开始时间和最后一次重复的结束时间)约为十个月。
  • @NeilMcGuigan 感谢您的评论。我同意数十亿真的太多了。我想说的是:事件具有复杂的时间模式,如何有效地处理它?每个用户都能够检索当前时刻的所有活动事件。近期(几天)的缓存时间计算解决了这个问题。但是当用户想要检索在特定时间活动的所有事件时,我真的不知道该怎么做。在创建时为每个事件生成所有时间间隔,会产生新问题:1. 将来编辑时间模式 2. 频繁重复的事件会产生大量垃圾数据
  • @AntonPererva 使用物化视图。尝试不同的时间窗口,例如 +-30 天或 +-365 天。制作原型。

标签: python django postgresql datetime calendar


【解决方案1】:

我会保留两个模型 - 一个用于描述重复规则,一个用于实际发生(每个规则可以有多次出现,但不是无限多,因为您声明它们具有“合理终止”)。

class Rule(models.Model):
    start = models.DateTimeField()
    end = models.DateTimeField()
    frequency = models.CharField(max_length=1, choices=FREQUENCIES)
    interval = models.PositiveIntegerField()
    duration = models.PositiveIntegerField() # duration may be in seconds or minutes?
    # and so on, add all the fields you need to define the rule

class Occurrence(models.Model):
    rule = models.ForeignKey(Rule)
    start = models.DateTimeField(db_index=True)
    end = models.DateTimeField(db_index=True)

给定一个 Rule 的实例,您可以使用 python-dateutil 中的 rrule 来生成它的所有 Occurrences 并将它们保存到数据库中。当然,会有很多,但这些都是小而简单的记录,数据库在有效处理方面没有问题。所以现在找到所有当前活动的 Occurrences 的问题是微不足道的:

Occurrence.objects.filter(start__lte=d, end__gte=d)

如果您想要规则实例而不是出现次数:

Rule.objects.filter(occurrence__start__lte=d, occurrence__end__gte=d)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-16
    • 1970-01-01
    • 2010-10-18
    • 2013-07-15
    • 2016-10-16
    • 2011-09-20
    • 1970-01-01
    相关资源
    最近更新 更多