【问题标题】:Best approach for tracking 'end_time' value for a table with 'start_time' and 'duration' columns跟踪具有“start_time”和“duration”列的表的“end_time”值的最佳方法
【发布时间】:2013-05-13 22:22:12
【问题描述】:

我有一个预先存在的“事件”表,其中包括一个 event_datetime 列和一个 event_duration_minutes 列。这两列分别是日期时间和整数。

我最近遇到了在活动结束时触发电子邮件的需要。为了实现这一点,我正在创建一个周期性工作,它每 10 分钟扫描一次数据库,以查找最近完成的事件。因此,我开始编写查询以查找在给定时间窗口内结束的所有事件,但由于每条记录的持续时间字段的可变性质,查询一直在逃避我。

我认为最好的方法是添加一个 end_time 列,然后自动将其设置为 start_time + 持续时间。这是正确的方法吗?

无论如何,我对如何进行查询完全空白 - 有没有一种简单的方法来处理这些情况?或者,这种查询的普遍需求是否表明您的数据库需要一些工作?

编辑 - 这是在 postgres 9.2 上。以下是我的 rails schema.rb 中的模式:

create_table "events", :force => true do |t|
  t.string   "title"
  t.text     "details"
  t.datetime "created_at",             :null => false
  t.datetime "updated_at",             :null => false
  t.datetime "event_datetime"
  t.integer  "instructor_id"
  t.integer  "event_duration_minutes"
  t.datetime "started_at_time"
end

【问题讨论】:

标签: sql postgresql relational-database


【解决方案1】:

通常的解决方案是在计算的结束时间上创建一个表达式索引。然后,您可以轻松地对其进行索引搜索。

最简单的方法是定义一个简单的 SQL 函数来执行计算,然后在表达式索引和要使用索引的查询中使用它。

例如:

CREATE OR REPLACE FUNCTION startduration_to_end(starttime timestamp, duration_minutes integer) RETURNS timestamp AS $$
SELECT $1 + $2 * INTERVAL '1' MINUTE';
$$ LANGUAGE sql;

然后:

CREATE INDEX mytable_end_index ON mytable 
( (startduration_to_end(event_datetime,event_duration_minutes ) );

根据查询模式,您可能需要另一个开始时间和结束时间,但如果表的更改率很高,请记住维护索引的成本:

CREATE INDEX mytable_end_index ON mytable 
(event_datetime, (startduration_to_end(event_datetime,event_duration_minutes ) );

您可以通过startduration_to_end 函数使用这些索引进行查询,例如:

SELECT *
FROM mytable t
WHERE startduration_to_end(t.event_datetime,t.event_duration_minutes) BETWEEN current_timestamp - INTERVAL '10' MINUTE AND current_timestamp;

由于执行时间的变化等原因,您确实应该扫描足够多的搜索重叠的索引,或者搜索比上次搜索的确切时间戳更新的所有内容,而不是最后 10 分钟。

【讨论】:

  • 我不知道表达式索引,但这很有意义。我在 Rails 环境中,所以我可能需要就实施咨询该社区。经过一些修补后会回来提供反馈。
  • @tealoque 是的,Rails 方面我帮不了你;我不太喜欢 ORM,如果可以避免的话,我会避免使用 Rails。
  • @tealoque 如果你在做时间范围,你可能会发现排除约束(根据文档)也很有趣
猜你喜欢
  • 2010-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-09
  • 2021-07-13
  • 1970-01-01
  • 1970-01-01
  • 2011-09-04
相关资源
最近更新 更多