Http 在web中使用PostgreSQL获取连续列表的最佳方法
我正在通过HTTP制作一个API,它通过分页从PostgreSQL获取许多行。在一般情况下,我通常通过naiveHttp 在web中使用PostgreSQL获取连续列表的最佳方法,http,postgresql,pagination,cursor,continuous,Http,Postgresql,Pagination,Cursor,Continuous,我正在通过HTTP制作一个API,它通过分页从PostgreSQL获取许多行。在一般情况下,我通常通过naiveOFFET/LIMIT子句实现这种分页。但是,在这种情况下有一些特殊要求: 有很多行,所以我相信用户无法到达终点(想象一下Twitter的时间线) 页面不必随机访问,只需按顺序访问即可 API将返回一个URL,其中包含指向连续块页面的游标标记 光标标记不必永久存在,而必须存在一段时间 它的排序经常波动(如Reddit排名),但是连续的游标应该保持其一致的排序 我怎样才能完成任务?我
OFFET
/LIMIT
子句实现这种分页。但是,在这种情况下有一些特殊要求:
- 有很多行,所以我相信用户无法到达终点(想象一下Twitter的时间线)
- 页面不必随机访问,只需按顺序访问即可
- API将返回一个URL,其中包含指向连续块页面的游标标记
- 光标标记不必永久存在,而必须存在一段时间
- 它的排序经常波动(如Reddit排名),但是连续的游标应该保持其一致的排序
- 当用户从第1页请求数据时。运行一个查询(包括order by、join checks等),将所有id存储到一个数组中(但最多500个id)。返回与数组中位于位置0-9的id:s对应的数据行
- 当用户请求第2-10页时。返回与位置处数组中id:s对应的数据行(第1页)*50-(第50页)*50-1页)李>
无论如何,希望这有帮助 假设只有结果的顺序波动,而不是行中的数据,Fredrik的答案是有意义的。但是,我建议添加以下内容:
- 使用类型而不是内存将id列表存储在postgresql表中。在内存中执行此操作,除非您小心地使用具有自动到期和内存限制的redis之类的工具,否则会使自己受到DOS内存消耗攻击。我想会是这样的:
create table foo_paging_cursor ( cursor_token ..., -- probably a uuid is best or timestamp (see below) result_ids integer[], -- or text[] if you have non-integer ids expiry_time TIMESTAMP );
- 您需要决定是否可以在用户之间共享游标标记和结果ID,以减少存储需求和每个用户运行初始查询所需的时间。如果它们可以共享,请选择一个缓存窗口,例如1或5分钟,然后根据新请求创建该时间段的缓存令牌,然后检查是否已计算该令牌的结果ID。如果不是,则为该令牌添加新行。您可能应该在check/insert代码周围添加一个锁,以处理对新令牌的并发请求
- 安排后台作业清除旧令牌/结果,并确保您的客户端代码可以处理与过期/无效令牌相关的任何错误
将结果ID保存在Redis列表中是处理此问题的另一种方法(请参阅命令),但如果您使用此方法,请小心过期和内存使用。您的Redis键将是游标标记,ID将是列表的成员。只是为了确定您的要求。你是说很多行还是很宽的行,或者两者都有?@StarShip3000谢谢。很多行。这只需要使用游标吗?因为还有其他方法不需要更好地管理游标,所以将其设置为临时表。更快,更少的磁盘负载。无需担心DOS攻击,临时表只能使用有限的RAM(当RAM不足时,读取并写入磁盘。临时表是会话本地表,在会话终止时会被删除。因此,在db连接池或http api端点分布在多个节点上并使用不同连接的情况下,这将不起作用。在安装appserver时,也会导致问题。)重新启动,必须重新连接到数据库。也就是说,将表放入内存支持的(通过tmpfs)表空间也可以获得同样的好处。请参阅,谢谢您的建议。我决定使用memcached,并将逗号分隔的ID存储到过期的键(光标标记)中。谢谢!