使用AWS分页AWS DynamoDB使用PHP
请有人对分页表中的记录有任何想法。其实我想用DynamoDb在php中创建一个分页组件。使用AWS分页AWS DynamoDB使用PHP
现在看来似乎是不可能给分页像<第一> <分组> 1,2,3,,5 ... <下一个> <最后>。
因为Dyanmodb只是给我们提供LIMIT条款,我们可以通过它来读取某些没有。的记录,我们可以通过LastEvaluatedKey处理下n个记录。所以如果我想直接跳到第5页,它可能怎么样?
根据我的理解,我们无法在分页中显示页码。我们可以做的只是读取记录的某些限制,并提供NEXT链接来检索下一个n记录。
分页是任何Web应用程序的基本特征,如果迁移到DynamoDb等云数据库,我们如何实现分页?
请提供您的意见和建议。谢谢
是的,您是对的,DynamoDB中没有OFFSET
。但只使用Limit
和LastEvaluatedKey
,我做了这个功能:
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的答案,迪纳摩将有非常可怕的分页性能,如果随机访问(即跳转到任意页)是所需的。但是,如果只执行下一页和上一页,则可以传递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
;然后,如果您再次发出扫描请求,请使用ExclusiveStartKey=3
进行第2页扫描,您将获得LastEvaluatedKey = 6
;要获得第3页,您可以使用LastEvaluatedKey = 6
..等进行另一次扫描。
您可以看到,如果没有任何形式的缓存,您将执行三次扫描(如果您在第3页之前还请求了第1页和第2页,则会重复其中的两次)。所以,我提出的优化是为每个页面存储相应的键。你会最终得到这样的地图:
Page | Hash-Key
------+----------
1 | null
2 | 3
3 | 6
.. | ...
而当你翻页结果时,这些值将被填写。现在,当用户想要第3页时,您只需执行一次扫描,使用6
作为ExclusiveStartKey
。
当然,对于每个页面大小,您都需要一个像这样的查找表,并且只有在新行被添加(或删除)之前,表才会准确无误。也就是说,如果你有很多请求,存储分页缓存所需的额外内存将非常值得。剩下的就是为你的分页缓存设置一个合理的到期时间,这取决于你的表中新增数据的频率(或删除)。
这样,没有大量缓存,对于性能来说会非常糟糕任何其他页面然后头几个 –
@MikeDinescu是的,我知道。有更好的解决方案 – Justinas
不,不是真的;我并不是说有一个更好的解决方案,只是在那里发出警告;我能想到的唯一改进就是确保缓存结果(或者至少是LastEvaluatedKey,这样后续调用不会受到每次扫描的惩罚) –