Postgres:使用时间戳进行分页

时间:2016-08-24 09:45:18

标签: postgresql

我有created(timestamptz)属性的表格。现在,我需要根据时间戳创建分页,因为当用户正在观看第一页时,可以将新项目提交到此表中,如果我使用OFFSET进行分页,这将使数据不一致。

所以,问题是:我应该将created类型保留为timestamptz,还是将其转换为整数(unix,例如1472031802812)更好。如果是这样,有什么缺点吗?另外,atm我在now()中有created作为默认值 - 是否有创建unix时间戳的替代函数?

2 个答案:

答案 0 :(得分:1)

让我从评论到我的答案重写内容。您希望使用timestamp类型而不是integer,因为它恰好是它的设计目标。在时间戳整数和timestamp对象之间进行手动转换只是一种痛苦而且你什么都得不到。最终,您将需要它来进行更复杂的基于日期时间的查询。

回答关于分页的问题。您只需进行查询

SELECT *
FROM table_name
WHERE created < lastTimestamp
ORDER BY created DESC
LIMIT 30

如果是第一次查询,则设置说lastTimestamp = '3000-01-01'。否则,您设置lastTimestamp = last_query.last_row.created

优化

请注意,如果表格很大,那么ORDER BY created DESC可能效率不高(特别是如果与不同范围并行调用)。在这种情况下,您可以使用移动&#34;时间窗&#34;,例如:

SELECT *
FROM table_name
WHERE
    created < lastTimestamp
    AND created >= lastTimestamp - interval '1 day'

1 day间隔是随意挑选的(根据您的需要调整)。您还可以在应用中对结果进行排序。

如果结果不为空,则更新(在您的应用中)

lastTimestamp = last_query.last_row.created

(假设您已完成排序,否则您将min(last_query.row.created)

如果结果为空,则使用lastTimestamp = lastTimestamp - interval '1 day'重复查询,直到您获取内容为止。此外,如果lastTimestamp变为低,则必须停止,即当它低于表中的任何其他时间戳(必须预取)时。

所有这些都是针对插入的假设:

  1. new_row.created >= any_row.created
  2. new_row.created ~ current_time
  3. new_row.created的分布或多或少均匀
  4. 假设1确保分页产生一致的数据,而假设2仅需要默认的3000-01-01日期。假设3是为了确保在必须发出许多空查询时不会有很大的空白。

答案 1 :(得分:0)

你的意思是这样的吗?

   select extract(epoch from now())::integer as unix_time