2014-05-03 180 views
4

請有人對分頁表中的記錄有任何想法。其實我想用DynamoDb在php中創建一個分頁組件。使用AWS分頁AWS DynamoDB使用PHP

現在看來似乎是不可能給分頁像<第一> <分組> 1,2,3,,5 ... <下一個> <最後>。

因爲Dyanmodb只是給我們提供LIMIT條款,我們可以通過它來讀取某些沒有。的記錄,我們可以通過LastEvaluatedKey處理下n個記錄。所以如果我想直接跳到第5頁,它可能怎麼樣?

根據我的理解,我們無法在分頁中顯示頁碼。我們可以做的只是讀取記錄的某些限制,並提供NEXT鏈接來檢索下一個n記錄。

分頁是任何Web應用程序的基本特徵,如果遷移到DynamoDb等雲數據庫,我們如何實現分頁?

請提供您的意見和建議。謝謝

回答

0

是的,您是對的,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'];(即 - 沒有任何搜索條件和沒有分頁,就像在正常分頁功能中一樣)。

+1

這樣,沒有大量緩存,對於性能來說會非常糟糕任何其他頁面然後頭幾個 –

+0

@MikeDinescu是的,我知道。有更好的解決方案 – Justinas

+0

不,不是真的;我並不是說有一個更好的解決方案,只是在那裏發出警告;我能想到的唯一改進就是確保緩存結果(或者至少是LastEvaluatedKey,這樣後續調用不會受到每次掃描的懲罰) –

0

要添加到@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

當然,對於每個頁面大小,您都需要一個像這樣的查找表,並且只有在新行被添加(或刪除)之前,表纔會準確無誤。也就是說,如果你有很多請求,存儲分頁緩存所需的額外內存將非常值得。剩下的就是爲你的分頁緩存設置一個合理的到期時間,這取決於你的表中新增數據的頻率(或刪除)。

+0

如果評論被刪除,您現在必須更新很多分頁索引號碼鍵,而不是一個好的解決方案所有。我相信刪除將是一個主要要求。 – Ouroboros

+0

@ P.Prasad - 不確定你的意思,但通常當你對結果進行分頁時,你希望通過什麼樣的快照進行分頁 - 刪除,就像插入會反映在後續分頁的結果中最終要求;取決於刪除和插入的頻率,您可以調整緩存的TTL,甚至使緩存無效 –

+0

如果項目編號4,5,6被刪除,則頁面密鑰映射中從頁面2開始的所有條目都必須是進行修改,使其值增加3.此操作本身是資源密集型的。 – Ouroboros