使用 Postgres 稳定分页

Stable pagination using Postgres

我想使用 Postgres 数据库作为后端来实现稳定的分页。稳定,我的意思是如果我使用一些分页标记重新阅读一个页面,结果应该是相同的。
使用插入时间戳将不起作用,因为时钟同步错误会使分页不稳定。
我正在考虑使用 pg_export_snapshot() 作为分页标记。这样,我可以在每次读取时重复使用它,并且数据库会保证我得到相同的结果,因为我总是使用相同的快照。但是文档说
“快照仅可用于导入,直到导出它的事务结束。” (https://www.postgresql.org/docs/9.4/functions-admin.html)
有什么解决方法吗?即使在事务关闭后,是否还有其他方法可以导出快照?

您不需要导出快照;您所需要的只是一个 REPEATABLE READ READ ONLY 事务,以便同一快照用于整个事务。但是,正如您所说,这是个坏主意,因为长事务很成问题。

使用插入时间戳,我发现 insert-only tables 没有真正的问题,但是删除或更新的行肯定会消失或移动,除非您使用“软删除和更新”并保留table 中的旧值(这给您带来了最终如何摆脱这些值的问题)。那将是 re-implementing PostgreSQL 在应用程序级别的多版本控制,看起来不太吸引人。

也许您可以使用可滚动的 WITH HOLD 游标。然后数据库服务器将在提交选择事务时具体化结果集,您可以随意向前和向后获取。当然,这会占用服务器资源,但您必须在某处付费。完成后不要忘记关闭光标。

如果您希望节省服务器资源,明显的替代方法是将整个结果集提取到客户端并单独在客户端实现分页。