postgresql - 如何在网络中使用 PostgreSQL 获取连续列表

标签 postgresql http pagination database-cursor continuous

我正在制作一个基于 HTTP 的 API,它通过分页从 PostgreSQL 中获取许多行。在一般情况下,我通常通过天真的 OFFET/LIMIT 子句来实现这种分页。但是,在这种情况下有一些特殊要求:

  • 有很多行,所以我相信用户无法到达终点(想象一下 Twitter 时间轴)。
  • 页面不必是随机访问的,但只能按顺序访问。
  • API 将返回一个 URL,其中包含指向连续 block 页面的游标标记。
  • 游标标记不必永久存在,而是存在一段时间。
  • 其顺序经常波动(如 Reddit 排名),但连续游标应保持一致的顺序。

我怎样才能完成任务?我已准备好为此更改我的整个数据库架构!

最佳答案

假设波动的只是结果的顺序而不是行中的数据,Fredrik 的回答是有道理的。但是,我建议添加以下内容:

  • 使用 array 将 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
    );
    
  • 您需要决定是否可以在用户之间共享 cursor_token 和 result_ids 以减少存储需求和每个用户运行初始查询所需的时间。如果它们可以共享,请选择一个缓存窗口,例如 1 或 5 分钟,然后根据新请求为该时间段创建 cache_token,然后检查是否已经为该 token 计算了结果 ID。如果不是,请为该标记添加一个新行。您可能应该在检查/插入代码周围添加一个锁,以处理对新 token 的并发请求。

  • 安排一个清除旧 token /结果的后台作业,并确保您的客户端代码可以处理与过期/无效 token 相关的任何错误。

甚至不要考虑为此使用真正的数据库游标。

将结果 ID 保留在 Redis 列表中是处理此问题的另一种方法(请参阅 LRANGE 命令),但如果您沿着这条路走下去,请注意过期和内存使用情况。您的 Redis 键将是 cursor_token,而 ID 将是列表的成员。

关于postgresql - 如何在网络中使用 PostgreSQL 获取连续列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7746920/

相关文章:

postgresql - Flyway - 通过引用 AWS ssm 参数和 secret 管理中的用户名和密码,使用 Flyway 在 postgres 数据库中创建带有密码的用户

ruby - 无法使用 'pg' gem 连接到 postgres?

sql - 插入 postgresQL

c# - 分页时出现算术溢出错误

postgresql - postgres autoincrement 未在显式 id 插入时更新

angular - Angular 中的 HTTP 错误处理

ios - 2017 年我是否会被迫在 HTTPS 中更新我的 iOS 应用程序?

asp.net - HTTP 模块和 HTTP 处理程序

java - 如何在 Google App Engine (Java) 中实现正确的分页?

php - 如何正确地将过滤器添加到该分页脚本中?