我有created
(timestamptz)属性表。现在,我需要根据时间戳创建分页,因为当用户正在观看第一页时,可以将新项目提交到此表中,这会使数据不一致,以防将分页使用OFFSET
。Postgres:使用时间戳分页
所以,问题是:我应该保留created
类型为timestamptz
或者最好将其转换为整数(unix,例如1472031802812
)。如果是这样,是否有缺点?另外,atm我有now()
作为created
的默认值 - 是否有替代函数来创建unix时间戳?
我有created
(timestamptz)属性表。现在,我需要根据时间戳创建分页,因为当用户正在观看第一页时,可以将新项目提交到此表中,这会使数据不一致,以防将分页使用OFFSET
。Postgres:使用时间戳分页
所以,问题是:我应该保留created
类型为timestamptz
或者最好将其转换为整数(unix,例如1472031802812
)。如果是这样,是否有缺点?另外,atm我有now()
作为created
的默认值 - 是否有替代函数来创建unix时间戳?
让我改写评论的东西到我的答案。您只想使用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
变为低电平,即当它低于表中的任何其他时间戳(必须预取)时,您也必须停止。
所有这一切是在某种假设为插入物:
new_row.created >= any_row.created
和new_row.created ~ current_time
new_row.created
分布是或多或少均匀假设1确保了分页结果在一致的数据中,假设2仅仅用于默认日期3000-01-01
。假设3是要确保当你不得不发出很多空查询时,你没有很大的空白。
你的意思是这样的吗?
select extract(epoch from now())::integer as unix_time
看起来很复杂)我的意思是,如果我有整数,我只会说'SELECT * FROM table_name WHERE created
将datetime保留为整数时间戳没有任何优势。其实这只会让事情变得复杂。例如想象一个查询“从月初开始给我所有的东西”。不要。 'timestamp'正是你需要的,使用它。 – freakish
@freakish,谢谢!如果我有整数,我只会说'SELECT * FROM table_name WHERE created
stkvtflw
我不确定我的理解。 'timestampz'不支持'<'运算符。你为什么要转换任何东西?我没有看到这一点。 – freakish