Предложите кому-нибудь понять, как разбивать записи из таблицы. На самом деле я хочу создать компонент paginate в php с DynamoDb.
Кажется, что невозможно присвоить разбивку на страницы как <first> <prev> 1,2,3, 4 , 5 … <next> <last>.
Потому что Dyanmodb просто предоставляет нам предложение LIMIT, с помощью которого мы можем прочитать некоторые нет. записей, и мы можем обрабатывать следующие n записей по LastEvaluatedKey. Поэтому, если я хочу перейти на 5-ю страницу, как это возможно?
По моему пониманию мы не можем отображать номера страниц в разбивке на страницы. Мы можем просто прочитать определенный лимит записей и предоставить ссылку NEXT для получения следующих n записей.
Пагинация – это основная функция любого веб-приложения. Как мы можем реализовать, если вы переносите в облачную базу данных, такую как 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
пока не 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
.. и так далее.
Вы можете видеть, что без какого-либо кэширования, чтобы выполнить три сканирования (два из которых были бы повторены, если вы также запросили страницы 1 и 2 до 3). Итак, моя предлагаемая оптимизация – хранить соответствующие ключи для каждой страницы. У вас будет такая карта:
Page | Hash-Key ------+---------- 1 | null 2 | 3 3 | 6 .. | ...
И значения будут заполняться, когда вы просматриваете результаты. Теперь, когда пользователю нужна страница 3, вам нужно всего лишь одно сканирование, используя 6
в качестве ExclusiveStartKey
.
Конечно, для каждого размера страницы вам понадобится таблица поиска, и таблица будет только точной, пока новые строки не будут добавлены (или удалены). Тем не менее, если у вас много запросов, дополнительная память, необходимая для хранения кэша поискового вызова, будет стоить того. Все оставлено тогда, чтобы установить разумное истечение срока для вашего кэша поискового вызова, в зависимости от того, как часто новые данные добавляются (или удаляются) в вашей таблице.