Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google cloud platform 如何实现分页?_Google Cloud Platform_Google Cloud Spanner - Fatal编程技术网

Google cloud platform 如何实现分页?

Google cloud platform 如何实现分页?,google-cloud-platform,google-cloud-spanner,Google Cloud Platform,Google Cloud Spanner,我有一个People表(Id,first\u name,last\u name),其中主键是Id。我希望能够查找表中按排序的前N个人(姓、名、Id)。在某些情况下,我需要查找接下来的N个人,以此类推。我想有效地做到这一点。最好的方法是什么?有两种主要方法: 使用限制和偏移 使用限制和上一页的键 偏移策略允许您读取任意页面,但效率不高,因为每次运行查询时,它都必须读取以前所有页面中的行。这是最容易实现的策略,也是可以接受的策略(特别是如果您只需要前几页),但通常不建议使用。“上一页”策略的关键

我有一个
People
(Id,first\u name,last\u name)
,其中主键是
Id
。我希望能够查找表中按
排序的前N个人(姓、名、Id)
。在某些情况下,我需要查找接下来的N个人,以此类推。我想有效地做到这一点。最好的方法是什么?

有两种主要方法:

  • 使用
    限制
    偏移
  • 使用
    限制
    和上一页的键
偏移策略允许您读取任意页面,但效率不高,因为每次运行查询时,它都必须读取以前所有页面中的行。这是最容易实现的策略,也是可以接受的策略(特别是如果您只需要前几页),但通常不建议使用。“上一页”策略的关键确实要求按顺序读取页面,但效率更高,因为每个页面只读取它需要的行

因此,让我们从原始查询开始,从按
(LastName,FirstName,Id)
排序的表中获取结果:

您可能希望确保所有查询都查看数据库数据的一致快照,因此您希望确保查询序列始终从相同的时间戳读取。最简单的方法是将第一个查询设置为只读事务,并将
returnReadTimestamp
设置为true。然后,后续查询也可以是只读事务,它们应该使用原始查询返回的时间戳作为其readTimestamp。请注意,无论您选择何种方法,
orderby
子句对于确保查询序列中的结果一致性至关重要。 假设返回的最后一行是
(1709,“John”,“Smith”)
。然后,第一次尝试查询以获取下一页结果可能如下所示:

SELECT
  t.id, 
  t.first_name, 
  t.last_name
FROM
  People as t
WHERE
  t.last_name > "Smith"
  OR
  (t.last_name = "Smith" and t.first_name > "John")
  OR
  (t.last_name = "Smith" and t.first_name = "John" AND t.id > 1709)
ORDER BY
  t.last_name,
  t.first_name,
  t.id
LIMIT
  @limit_rows

中间的
WHERE
子句是新的。但是写这个谓词比你想象的要复杂。您可能必须处理空值。您必须处理多个名为John Smith的人具有不同
id
值的情况。您需要非常小心使用浮点数和
NaN
值。Cloud Panner的Read API在这种情况下也很有用,因为它使在表上对范围扫描进行分页变得更容易。

Hi Mike,感谢您发布这篇文章。如果您正在使用快照并提供时间戳,那么为什么需要添加所有这些where约束呢。你就不能说t.id>1709吗?或者,您是在试图说明快照由于垃圾收集而过期的情况吗?垃圾收集与此无关。额外约束的原因是,问题说我们希望按(Lastname、Firstname、Id)的顺序返回查询结果,这与主键顺序不同。注意,可能有一个t.id小于1709的结果仍然是需要的结果(例如“Wilkes”、“Bob”805)
SELECT
  t.id, 
  t.first_name, 
  t.last_name
FROM
  People as t
WHERE
  t.last_name > "Smith"
  OR
  (t.last_name = "Smith" and t.first_name > "John")
  OR
  (t.last_name = "Smith" and t.first_name = "John" AND t.id > 1709)
ORDER BY
  t.last_name,
  t.first_name,
  t.id
LIMIT
  @limit_rows