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

jst*_*tol 3 sql postgresql rest pagination go

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

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

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

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

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

Cra*_*ger 8

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

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

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

  • 保持每个客户的不同状态

这是一种"挑选任何两种"的情况.你必须妥协; 接受你不能让每一个客户的分页状态完全正确的,接受你必须下载一个大的数据集到客户端,或接受,你必须使用一个巨大的服务器资源量,以保持客户端状态.

那些混合了各种妥协的变化,但这就是它归结为什么.

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

有些系统将缓存客户端状态在短期内(与短暂的未注册的表,临时文件,或其他),但很快就到期了,所以如果客户没有不断地问新鲜数据的得到打破分页.

等等.

也可以看看:

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

  • 使用游标,读取并立即将第一部分数据发送到客户端.

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

  • 在最近最少使用的基础上使缓存过期,因此如果客户端没有足够快地读取它们,则必须从DB获取一组新数据,并且分页更改.

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

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