一尘不染

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

go

我正在创建一个RESTfulWeb服务(在Golang中),该服务从数据库中提取一组行并将其返回给客户端(智能手机应用程序或Web应用程序)。该服务需要能够提供分页。唯一的问题是,此数据在定期更改的“计算”列上排序(例如,网站上某内容的“竖起大拇指”或“竖起大拇指”的数量),因此
行可以在在客户的要求之间

我看了一些PostgreSQL功能,可以用来帮助解决此问题,但是似乎没有什么是一个很好的解决方案。

  • 物化视图:用于保存“陈旧的”数据,该数据仅偶尔更新一次。这并不能真正解决问题,因为如果在更新实例化视图时用户恰好在分页浏览数据,数据仍然会跳来跳去。
  • 游标:为每个客户会话创建并在请求之间保持。如果同时有很多并发会话,这将是一场噩梦。

是否有人在客户端或数据库方面对如何处理此问题有任何建议?我真的有什么可以做的,还是通常由消耗数据的客户端来解决这样的问题?

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


阅读 382

收藏
2020-07-02

共1个答案

一尘不染

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

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

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

  • 为每个客户端维持不同的状态

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

这些差异中包含了各种折衷,但这就是所有这些。

例如,有些人会向客户发送 一些 额外的数据,足以满足大多数客户的需求。如果客户超过此限制,那么分页就会失败。

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

等等。

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

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

  • 立即从游标中获取足够的额外数据,以满足99%的客户要求。将其存储到诸如memcached,Redis,BigMemory,EHCache之类的快速,不安全的缓存中,无论使用哪种密钥,该密钥都可以让我为同一客户端的后续请求检索它。然后关闭游标以释放数据库资源。

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

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

这样,大多数客户端将不会注意到分页问题,​​并且您不必向大多数客户端发送大量数据,但是您不会融化数据库服务器。但是,您需要一个很大的缓存来解决此问题。它的实用性取决于您的客户是否可以应对分页中断-
如果根本无法接受分页中断,那么您将不得不在游标,临时表,在第一次请求时处理整个结果集等方面在数据库端进行操作。它还取决于数据集的大小以及每个客户端通常需要多少数据。

2020-07-02