【问题标题】:How to keypaginate UUID in postgresql?如何在 postgresql 中对 UUID 进行键盘分页?
【发布时间】:2019-11-19 21:07:34
【问题描述】:

我想以最好的方式对包含 10k+ 个寄存器的用户表进行分页。我可以使用偏移量和限制,但正如我在许多文章中看到的那样,它显然不是很好。偶然发现了键集和光标分页,我认为键集可能更合适,因为它更容易在 API 中实现(我使用 golang)。问题是键集是如何工作的,据我所知,id(主键)被索引,然后用于跨数据库查询:

select * from users where id > ? order by id limit ?

但是,这似乎只在整数自动增量 ID 中可行,这不是我的情况,我使用的是 UUID (v4)。 我怎样才能实现这个键集分页?

【问题讨论】:

  • 那里没有任何东西只限于整数。你可以使用 UUID 就好了。这确实意味着您必须按 UUID 顺序翻页,这可能不是最自然的排序方式。但是你有一个你想要的自然顺序,你需要提到它。
  • 假设我会按名称订购。我需要设置索引,获取第一次加载的数据(限制500),然后获取最后一个ID,并在where id > ID? select * from user where id > ? (我猜这是空的)限制 500; select * from user where id > uuidfromlastrow limit 500;
  • 如果您想订购名称,那么您只需将 uuid 用作决胜局,而不是主要。 WHERE (name, id)>(?,?) order by name, id limit 500
  • 我只是想命令它进行分页,真正的排序将在客户端使用请求片段完成(很好的例子quasar.dev/vue-components/…)。我在您的代码中看到了一些带有日期(created_at/updated_at)的示例,uuid 如何在该查询中进行交互?如果我按日期过滤,uuid 不会没用吗?

标签: postgresql indexing uuid


【解决方案1】:

这对 UUID 也同样适用。假设id是UUID主键列,可以这样写

SELECT ... FROM ...
WHERE (order_col1, order_col2, id) > (<previous values>)
ORDER BY order_col1, order_col2, id
LIMIT <page size>;

(order_col1, order_col2) 上的索引可以支持此查询。

【讨论】:

  • 我测试了它,它是真的,UUID 无关紧要(那么多),但是,我还有另一个问题,我怎么能按 4 列 +(一次)排序并过滤所有只有一个过滤器的列(例如输入文本)?
  • 我不太明白。您应该提出一个新问题并提供更多详细信息。
  • 我不知道你可以在一个 Postgresql 表达式中比较多个值!我想在他们的文档中了解更多信息。这种比较叫什么? WHERE (order_col1, order_col2, id) &gt; (&lt;previous values&gt;)
  • @EugeneKim 我不认为有什么特别的名字,它是行表达式复合类型的比较。我不知道文档是否具体涵盖了这一点,但比较是按字典顺序进行的:首先,比较第一个元素。如果这还不足以确定结果,则比较第二个元素,依此类推。
  • 感谢@LaurenzAlbe 的回复。在官方文档中提到一些东西会很好,但在堆栈溢出和像你这样乐于助人的人的世界里,这可能并不重要。干杯!
猜你喜欢
  • 2019-01-15
  • 2020-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-25
  • 2016-08-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多