2016-08-24 51 views
0

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

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

+1

将datetime保留为整数时间戳没有任何优势。其实这只会让事情变得复杂。例如想象一个查询“从月初开始给我所有的东西”。不要。 'timestamp'正是你需要的,使用它。 – freakish

+0

@freakish,谢谢!如果我有整数,我只会说'SELECT * FROM table_name WHERE created stkvtflw

+0

我不确定我的理解。 'timestampz'不支持'<'运算符。你为什么要转换任何东西?我没有看到这一点。 – freakish

回答

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可能不是有效的(特别是如果有不同的范围称为平行)。在这种情况下,你可以使用移动的“时间窗口”,例如:

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

1 day间隔arbitrarly采摘(调整它以您的需求)。您也可以在应用程序中排序结果。

如果结果不为空,则进行更新(在您的应用程序)

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分布是或多或少均匀

假设1确保了分页结果在一致的数据中,假设2仅仅用于默认日期3000-01-01。假设3是要确保当你不得不发出很多空查询时,你没有很大的空白。

+0

谢谢!一个问题:如果我将创建基于'created'的索引,'DESC'仍然不会有效吗? – stkvtflw

+0

@stkvtflw如果我们谈论数亿行,那么是的。但在你选择任何战略基准之前。 – freakish

+0

对不起,再次打扰你,但我还有一个非常最后一个问题)如何将unix时间戳与MILLISECONDS转换为postgres-acceptable-timestamptz? – stkvtflw

0

你的意思是这样的吗?

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

看起来很复杂)我的意思是,如果我有整数,我只会说'SELECT * FROM table_name WHERE created stkvtflw

相关问题