使用更改排序顺序处理分页

时间:2014-10-04 00:42:24

标签: sql postgresql rest go pagination

我正在创建一个RESTful Web服务(在Golang中),它从数据库中提取一组行并将其返回给客户端(智能手机应用程序或Web应用程序)。该服务需要能够提供分页。唯一的问题是这些数据是根据经常变化的"计算的"列(例如,"赞成"或"拇指向下"网站上的一段内容有),因此行可以在a之间跳转页码客户的要求

我已经看过一些可能用来帮助我解决这个问题的PostgreSQL功能,但似乎没有什么比这更好的解决方案了。

  • 物化观点:持有"陈旧"每隔一段时间才更新一次的数据。这并没有真正解决问题,因为如果用户在物化视图更新时正好翻阅数据,数据仍会跳转。
  • 游标:为每个客户端会话创建并在请求之间保持。如果同时有很多并发会话(这将会是),这似乎是一场噩梦。

在客户端或数据库端,是否有人对如何处理此问题有任何建议?有什么我真的可以做的,或者这个问题通常只是由消费数据的客户补救?

编辑我应该提到智能手机应用程序允许用户通过“无限滚动”来查看更多数据,因此它会跟踪它自己的数据客户端数据列表。

2 个答案:

答案 0 :(得分:7)

这是一个没有完全令人满意的解决方案的问题,因为你试图结合基本上不兼容的要求:

  • 按需向客户端发送所需数量的数据,即您无法下载整个数据集,然后在客户端对其进行分页。

  • 最大限度地减少服务器必须跟踪的每个客户端状态的数量,以实现具有大量客户端的可扩展性。

  • 维护每个客户的不同状态

这是一种“挑选任何两种”的情况。你必须妥协;接受您不能完全正确地保持每个客户的分页状态,接受您必须将大数据集下载到客户端,或者接受您必须使用大量服务器资源来维护客户端状态。

在那些混合各种妥协的变化中,但这就是归结为它。

例如,有些人会向客户端发送一些额外数据,足以满足大多数客户的要求。如果客户端超过了那个,那么它就会破坏分页。

有些系统会在短时间内缓存客户端状态(使用短期未记录的表,临时文件或其他任何内容),但会很快过期,因此如果客户端不经常要求新数据,则会破坏分页。

另见:

我可能会实现某种形式的混合解决方案,例如:

  • 使用游标,阅读并立即将第一部分数据发送给客户。

  • 立即从游标中获取足够的额外数据,以满足99%的客户需求。将它存储到一个快速,不安全的缓存中,例如memcached,Redis,BigMemory,EHCache,无论是什么密钥都可以让我检索它以供同一客户端的后续请求。然后关闭光标以释放数据库资源。

  • 在最近最少使用的基础上使缓存过期,因此如果客户端不能保持足够快的读取速度,则必须从数据库中获取一组新数据,并且分页会发生变化。

  • 如果客户希望获得比绝大多数同行更多的结果,那么当您切换到直接从数据库而不是缓存中读取或生成新的更大的缓存数据集时,分页会在某些时候发生变化。

这样大多数客户都不会注意到分页问题而且您不必向大多数客户端发送大量数据,但您不会融化您的数据库服务器。但是,你需要一个很好的缓存来逃脱这个。它的实用性取决于你的客户是否能够应对分页 - 如果打破分页是不可接受的,那么你就会坚持使用游标,临时表,在第一次请求时应对整个结果集等等。它还取决于数据集大小以及每个客户端通常需要的数据量。

答案 1 :(得分:0)

我不知道这个问题的完美解决方案。但是,如果您希望用户拥有数据的陈旧视图,那么光标就是您的选择。您只能进行调整,只能存储光标中前2页的数据。除此之外,你再次获取它。