游戏排行榜前 10 名得分 dynamoDB nodejs sdk 查询
Posted
技术标签:
【中文标题】游戏排行榜前 10 名得分 dynamoDB nodejs sdk 查询【英文标题】:Top 10 scores for game leaderboard dynamoDB nodejs sdk query 【发布时间】:2021-10-22 13:28:12 【问题描述】:我有一个具有以下字段的 dynamodb -
id (primary key) (string)
name (user name) (string)
score (sort key) (number)
player (type - regular/new etc.) (string)
我只是想从数据库中获得前 10 名。 按照 AWS https://docs.aws.amazon.com/AWSjavascriptSDK/latest/AWS/DynamoDB.html#query-property的文档尝试了几个查询
这是我的查询代码-
const ddb = new AWS.DynamoDB.DocumentClient(apiVersion: '2012-08-10');
function getItems()
var params =
ExpressionAttributeValues:
":v1":
S: "regular"
,
KeyConditionExpression: "player = :v1",
TableName: "cloudtag_result"
;
return ddb.scan(params).promise();
但它给了我以下错误
2021-08-21T08:36:43.092Z 1bbd5490-4248-4f06-94ea-724e6d23dac5 ERROR ValidationException: Query condition missed key schema element: id
at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/json.js:52:27)
at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:688:14)
at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:690:12)
at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:116:18)
code: 'ValidationException',
time: 2021-08-21T08:36:43.031Z,
requestId: 'JH91VON2KGVNP7HF41VCBELTUVVV4KQNSO5AEMVJF66Q9ASUAAJG',
statusCode: 400,
retryable: false,
retryDelay: 47.72972319109784
【问题讨论】:
【参考方案1】:DynamoDB 有一个基本限制,即您绝对必须在所有查询中指定分区键(或您所称的主键)。它必须与表中的内容完全匹配,不允许“模糊”查询。
您在player = ..
上查询,但您没有指定 id。没有办法让它在发电机中工作,你需要指定主键。
如果您的访问模式要求您能够按玩家名称查找,则您需要将玩家名称放在 PK 或 SK 中,否则您需要在您的应用程序中而不是在 dynamodb 服务器上进行过滤.
您可能想要所谓的“单表设计”。 Rich Houlihan 的这次演讲强烈推荐给任何使用 dynamo 进行数据建模的人 :)
https://www.youtube.com/watch?v=HaEPXoXVf2k
【讨论】:
【参考方案2】:您可以为此创建一个全球二级索引 (GSI)。
将player
作为您的GSI 分区键,将score
作为您的GSI 排序键,您实际上可以针对这个GSIquery /strong> 通过提供player
的值并使用scanIndexForward (true/false)
根据GSI 排序键 以升序或降序获取数据。
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html
但是,当您的数据变大时,您可能会在 GSI 上遇到Hot Partition
问题,这是由于 GSI 分区键 过于集中在指定键,例如regular
。因此,如果您可以开始进行分区键分片会更好,您可以在player
中添加一个后缀,例如regular#1, regular#2... regular#n
。这样就可以避免Hot Partition
的问题了。
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-partition-key-sharding.html
同样,如果您采用此解决方案,您将需要在 GSI
上执行 n times
查询,以获取每个分区中由于分区键分片而获得的前几名得分者,然后您将使用代码进行排序。
【讨论】:
以上是关于游戏排行榜前 10 名得分 dynamoDB nodejs sdk 查询的主要内容,如果未能解决你的问题,请参考以下文章
在 Google Play 游戏中更新(递增/递减)排行榜得分
2022年4月中国数据库排行榜:华为GaussDB 挺进前四,榜单前八得分扶摇直上