繁体   English   中英

使用PHP的AWS DynamoDB分页

[英]Pagination with AWS DynamoDB with PHP

有人知道从表中分页记录。 其实我想在php中使用DynamoDb创建一个paginate组件。

现在看来似乎是不可能给分页像<第一次> <前> 1,2,3,4,5 ... <下> <最后>。

因为Dyanmodb只是提供了我们LIMIT条款,我们可以通过它来阅读某些号码。 记录,我们可以通过LastEvaluatedKey处理下n个记录。 所以,如果我想直接跳到第5页,怎么可能?

根据我的理解,我们无法将页码显示在分页中。 我们能做的就是读取某些记录限制并提供NEXT链接来检索下n条记录。

分页是任何Web应用程序的基本功能,如果迁移到像DynamoDb这样的云数据库,我们如何实现?

请提供您的意见和建议。 谢谢

是的,你是对的,DynamoDB中没有OFFSET 但是只使用LimitLastEvaluatedKey ,我做了这个功能:

public function scan($table, $filter = [], $select = null, $limit = 2)
{
    $page = isset($_GET['page']) ? $_GET['page'] : 0;
    $options = [
        'TableName' => $table,
        'Count' => true,
    ];

    if (!empty($limit)) {
        $options['Limit'] = $limit;
    }

    if (!is_null($select)) {
        $options['Select'] = $select;
    }

    if (!empty($filter)) {
        $options['ScanFilter'] = $filter;
    }

    $results = $results = $this->_client->scan($options);

    while ($page > 0 && isset($results['LastEvaluatedKey'])) {
        $results = $results = $this->_client->scan($options);
        $options['ExclusiveStartKey'] = $results['LastEvaluatedKey'];
        $page--;
    }

    return $results;
}

$this->_client是指DynamoDb客户端对象。
基本上我用LastEvaluatedKey循环遍历所有条目,直到我到达所需的页面。
要获取表中的总条目,请调用$this->scan($this->tableName(), [], null, null)['Count']; (即 - 没有任何搜索条件且没有分页,就像在正常的分页功能中一样)。

为了增加@Justinas的答案,如果需要随机访问(即跳转到任意页面),Dynamo将具有相当可怕的分页性能。 但是,如果您只执行下一页和上一页,则可以传递LastEvaluatedKey并将扫描的开销保持在最低限度。

如评论中所述,您应该尽可能地缓存结果。 至少可以缓存LastEvaluatedKey结果,以便在用户翻阅结果时不需要为每个分页请求重新计算它们。 这是我的意思的一个例子:

假设您有一个具有这样的模式的表,其中CommentID是散列键。

 CommentID | Author | Comment | ...
-----------+--------+---------+------------
    1      | Joe    | Foo     | ...
    2      | Joe    | Bar     | ...
    3      | John   | Baz     | ...
    4      | Joe    | FooBar  | ...
    5      | Jane   | BooBaz  | ...
    6      | Joesie | Blah    | ...
    7      | Johnny | Blahaha | ...

当您开始分页时,假设您每页请求3条评论,您将获得第一页结果和LastEvaluatedKey = 3 ; 然后,如果您针对第2页发出第二个扫描请求,则使用ExclusiveStartKey=3您将获得LastEvaluatedKey = 6 ; 要获得第3页,您将使用LastEvaluatedKey = 6进行另一次扫描..依此类推。

您可以看到,在没有任何缓存的情况下,您要执行三次扫描(如果您还请求第3页之前的第1页和第2页,则会重复其中两次扫描)。 因此,我建议的优化是为每个页面存储相应的键。 你最终得到这样的地图:

 Page | Hash-Key
------+----------
   1  |   null
   2  |     3
   3  |     6
  ..  |    ... 

当您翻阅结果时,这些值将被填写。 现在,当用户想要第3页时,您所要做的就是一次扫描,使用6作为ExclusiveStartKey

当然,对于每个页面大小,您需要一个这样的查找表,并且只有在添加(或删除)新行之前,该表才是准确的。 也就是说,如果你有很多请求,那么存储分页缓存所需的额外内存将非常值得。 剩下的就是为您的分页缓存设置合理的到期时间,具体取决于在表中添加(或删除)新数据的频率。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM