DynamoDB 建模问题:table 玩家 1 和玩家 2 之间的游戏,如何获得涉及给定玩家的所有游戏
DynamoDB modelling question: table with games between player1 and player2, how to get all games involving a given player
正在将游戏存储在数据库中。游戏在两个玩家之间进行:称他们为玩家 1 和玩家 2。每个游戏我都有一个文档,其中包含玩家 ID 的键 'player1' 和 'player2'。显然,根据平局,给定的玩家可能会出现在 player1 或 player2 键中。
有没有一种方法可以构建我的数据,以便我可以高效地找到给定玩家的所有游戏?我知道 player1=playerId 或 player2=playerId 的查询在 dynamo 中是不可能的。我正在寻找有关如何管理它的想法。我首先创建“链接”文档,其中 playerId 作为分区键,date/time of game 作为排序键。但这越来越乱了!
也许我最好的选择是创建两个 GSI(在 player1 和 player2 上)并进行应用程序级联合。
谢谢
如果我没看错你的问题,你的访问模式是
- 为玩家获取游戏
- 为玩家获取最近的游戏(基于之前 post 的评论)
让我们从对玩游戏的两个玩家之间的关系建模开始。我将其称为匹配(很难命名)。您可以像这样存储玩家之间的比赛:
我在 Match 项上添加了一些属性来说明这个概念。我正在使用格式为 MATCH#[KSUID] 的简单主键。如果您不熟悉,KSUID 是一个唯一标识符,因此 table 和 具有 built-in 时间分量。您可以像使用 UUID 一样使用它们,但可以获得基于时间的可排序性的有用副作用。 KSUID 的这个特性在检索最新的比赛时会很有用。
我们可以创建两个二级索引来从任一玩家的角度对比赛进行建模。例如,我将创建一个名为 Player1Index 的二级索引,并为其提供 player1
属性的 GSIPK,而 GSISK 可以是主 table 的 PK
。使用上面的示例,您的数据将如下所示
同样,Player2Index 看起来像这样
请注意,KSUID 是两个索引中排序键的一部分,这意味着玩家获取比赛将自动按照比赛的创建顺序对比赛进行排序。这将允许您的第二个访问模式,您可以在其中获取给定玩家的最新比赛。
编辑:如果目标是获得所有场比赛,其中给定球员是球员1 或球员2,您可以创建比赛项目将每个玩家作为集合中的单独项目包含的集合。例如:
然后您可以创建倒排二级索引,交换索引中的 PK/SK 模式。看起来像这样:
在此模型中,二级索引将包含给定球员的 所有 场比赛,无论他们在比赛中的角色如何。您可能更喜欢此解决方案,因为您可以使用单个索引在单个查询中获取数据。分页会比第一种方法更容易。
无论您采取哪种方式,目标都是 pre-join 您需要的数据,以便可以在单个查询中获取。当然,您可以使用前一种模式并查询两个索引,然后在您的应用程序中合并结果。进行两次查询(相对于一次查询)并不是世界上最糟糕的事情,但比一次获取所有数据更令人不满意!
正在将游戏存储在数据库中。游戏在两个玩家之间进行:称他们为玩家 1 和玩家 2。每个游戏我都有一个文档,其中包含玩家 ID 的键 'player1' 和 'player2'。显然,根据平局,给定的玩家可能会出现在 player1 或 player2 键中。
有没有一种方法可以构建我的数据,以便我可以高效地找到给定玩家的所有游戏?我知道 player1=playerId 或 player2=playerId 的查询在 dynamo 中是不可能的。我正在寻找有关如何管理它的想法。我首先创建“链接”文档,其中 playerId 作为分区键,date/time of game 作为排序键。但这越来越乱了!
也许我最好的选择是创建两个 GSI(在 player1 和 player2 上)并进行应用程序级联合。
谢谢
如果我没看错你的问题,你的访问模式是
- 为玩家获取游戏
- 为玩家获取最近的游戏(基于之前 post 的评论)
让我们从对玩游戏的两个玩家之间的关系建模开始。我将其称为匹配(很难命名)。您可以像这样存储玩家之间的比赛:
我在 Match 项上添加了一些属性来说明这个概念。我正在使用格式为 MATCH#[KSUID] 的简单主键。如果您不熟悉,KSUID 是一个唯一标识符,因此 table 和 具有 built-in 时间分量。您可以像使用 UUID 一样使用它们,但可以获得基于时间的可排序性的有用副作用。 KSUID 的这个特性在检索最新的比赛时会很有用。
我们可以创建两个二级索引来从任一玩家的角度对比赛进行建模。例如,我将创建一个名为 Player1Index 的二级索引,并为其提供 player1
属性的 GSIPK,而 GSISK 可以是主 table 的 PK
。使用上面的示例,您的数据将如下所示
同样,Player2Index 看起来像这样
请注意,KSUID 是两个索引中排序键的一部分,这意味着玩家获取比赛将自动按照比赛的创建顺序对比赛进行排序。这将允许您的第二个访问模式,您可以在其中获取给定玩家的最新比赛。
编辑:如果目标是获得所有场比赛,其中给定球员是球员1 或球员2,您可以创建比赛项目将每个玩家作为集合中的单独项目包含的集合。例如:
然后您可以创建倒排二级索引,交换索引中的 PK/SK 模式。看起来像这样:
在此模型中,二级索引将包含给定球员的 所有 场比赛,无论他们在比赛中的角色如何。您可能更喜欢此解决方案,因为您可以使用单个索引在单个查询中获取数据。分页会比第一种方法更容易。
无论您采取哪种方式,目标都是 pre-join 您需要的数据,以便可以在单个查询中获取。当然,您可以使用前一种模式并查询两个索引,然后在您的应用程序中合并结果。进行两次查询(相对于一次查询)并不是世界上最糟糕的事情,但比一次获取所有数据更令人不满意!