簡體   English   中英

查詢項目以排除 DynamoDB 中已知鍵子集的最佳模式?

[英]Best pattern to query items to exclude a subset of known keys in DynamoDB?

我正在制作一款玩家玩關卡的游戲。 沒有順序(這是我想要動態提供的)。

我想為玩家提供他們未玩過的所有關卡,即使創建了新關卡。 問題是這是一個NOT和JOIN操作,在dynamodb中顯然是不存在的。 有辦法嗎?

我可以在級別 createTime 上保留索引並將 lastPlayedCreateTime 保存到播放器 object,然后查詢該時間之后的所有級別。 然而,我只堅持那個索引。 這有一個好的模式嗎? 例如,我無法將其更改為在按“級別難度”排序的未播放級別上提供服務。

現在我做了 2 個查詢:對於用戶玩過的所有級別,然后是全局所有級別,然后從我的應用程序中過濾/排序和服務。 感覺可能有更好的方法,如果每個方法都有很多,那么這實際上行不通。

我主要使用以下 PK 和 SK 執行此操作:[UID#userId, LVL#lvlId] 查詢每個玩家級別的統計信息,以及 [LVL, LVL#lvlid] 查詢所有級別。

另一個例子:Tinder 如何顯示你以前沒見過的人? (雖然可能會改變順序)

這是一個有趣的謎題。 這基本上是一個算法問題。 問題是是否有一種算法即使在大規模情況下也能有效地做到這一點。

似乎您可能有一個假設,如果您可以只表達一個連接,那么事情會很好,但這種連接在規模上可能會非常昂貴。 這就是為什么 DynamoDB 不會讓你有一些表達簡單但執行起來困難的東西。 它使痛苦看起來不痛苦。

您不會提供影響此類設計的大多數關鍵因素的統計數據。 我要做出假設。 我假設有 100 個難度,每個都有一百萬個級別 (ID),有一百萬個玩家,玩家可以玩過大部分級別,並且隨着時間的推移隨機添加新級別,每個級別都有不同的難度。

您目前正在遵循一種設計,在該設計中,您詳盡地列出了玩家玩過的所有關卡,並與現有的關卡列表進行交叉檢查。 這本質上是 O(n) 級數。 不是很好。 如果這個人已經玩了 999,999 個關卡,那么你要花很多功夫才能找到剩下的 1 個關卡。

我更喜歡你的想法,你只是為每個玩家保留一個“書簽”,記錄他們在每個難度下的進步。 然后你可以在給定難度的書簽之后獲取下一個級別並更新書簽。

因此,級別添加了difficulty的 PK 和creationTime的 SK。 額外的屬性包括查找 ID 或其他任何內容。

玩家被添加了玩家 ID 的 PK 和 SK 作為復合<difficulty>#<creationTimeBookmark>

PK SK 有效載荷
UID#1 差異#1#2022-01-05
UID#1 差異#2#2022-01-05
UID#2 差異#1#2022-01-07
UID#2 差異#2#2022-01-06
差異#1 2022-01-05 編號#a
差異#1 2022-01-06 編號#b
差異#1 2022-01-07 編號#c
差異#2 2022-01-05 編號#d
差異#2 2022-01-06 編號#e
差異#2 2022-01-07 編號#f

要找到玩家的下一個級別,您需要確定您想要的難度,查詢他們當前具有該難度的書簽,獲取該書簽之后的下一個項目,然后使用該新書簽更新玩家。 很簡單:獲取、查詢、更新 singleton 個值。

當你添加新的關卡時,它們 go 到最后,所以它工作正常。

如果你想要更接近隨機性的東西,那么我可能建議每個玩家開始時為每個難度設置一個隨機的起始書簽,並啟用循環,這樣當你到達終點時,你就會從頭開始。 要處理添加,您需要跟蹤它們的起點和循環點,以便當它們到達原來的起點時,您可以在循環點繼續前進。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM