【问题标题】:Offset queries for non-unique columns非唯一列的偏移量查询
【发布时间】:2015-06-14 09:27:03
【问题描述】:

假设我有一张这样的桌子:

CREATE TABLE book (
 id INTEGER PRIMARY KEY,
 title VARCHAR(32) NOT NULL
);

我想支持带偏移量的查询,以支持返回书籍列表的 API,按 non-unique 具有给定偏移量和限制的标题字段排序。

这里的问题是什么是最有效的方法 [1] 为非唯一的 title 列定义唯一索引(或辅助列或类似的东西)可以用作查询中的不透明偏移标记我正在使用ORDER BY title。我考虑过在函数上创建一个索引,该索引将返回一行的唯一数字位置,但我担心这会严重影响大表的 INSERT 和 UPDATE 时间,我认为有一个最佳解决方案。

虽然这对于 ORDER BY {unique_field} 查询 [2] 来说很简单,但我没有看到一种简单的方法来实现非唯一字段的相同。

另外让我们假设解决方案应该在 postgresql 和 mysql 中工作。


注意事项:

[1] 由于像 SELECT id, title FROM book ORDER BY title OFFSET [number] LIMIT [number] 这样简单的解决方案对于大数值偏移值非常不利,因此我将引入某种不透明标记来表示偏移量我的 API 中用于获取书块的给定集合。

因此,API 方法将返回按标题排序的书籍列表并具有给定的偏移量,如下所示(伪代码):

BookPage getBooks(optional string offsetToken, int limit)

其中BookPage定义如下:

class BookPage {
 nonnull List<Book> books;
 nonnull string offsetToken; // expected to be used to return a next page
}

示例使用,book table 包含 2*N 个书:

// 1st call
BookPage page1 = getBooks(null, 2); // get first 2 books
BookPage page2 = getBooks(page1.offsetToken, 2); // get next 2 books
BookPage page3 = getBooks(page2.offsetToken, 2); // get next 2 books
//...
BookPage pageN = getBooks(pageN-1.offsetToken, 2); // get last 2 books

列表 page1.books、page2.books、... pageN.books 的串联将生成按标题升序排列的书籍列表。

[2] 例如:如果 getBooks API 将使用偏移查询,其中按 id 排序的书籍(这是一个主键) offsetToken 将是最后一本书的 id 并且 getBooks API 的实现如下所示(伪代码):

BookPage getBook(optional string offsetToken, int limit) {
 Long startId = (offsetToken != null ? toLong(offsetToken) : null);
 page.books = (SELECT id, title FROM books 
               WHERE :startId IS null OR id>:startId
               ORDER BY id
               LIMIT :limit);
 page.offsetToken = toString(lastElementOf(page.books).id)
 return page;
}

【问题讨论】:

    标签: sql offset


    【解决方案1】:

    到目前为止,我发现的最简单和最简单的解决方案是将非唯一列与主键结合使用。它使选择查询稍微复杂化 - 例如对于原始问题,您需要编写类似 (title = :title AND id > :id) OR (title > :title) 的内容,其中 :title 和 :id 构成 offsetToken(最后一项的标题和 id)。

    【讨论】:

      猜你喜欢
      • 2012-05-30
      • 2017-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-18
      • 1970-01-01
      • 1970-01-01
      • 2016-10-23
      相关资源
      最近更新 更多