如何设计 DynamoDB table 模式

How to design a DynamoDB table schema

我正在尽我最大的努力去理解 DynamoDB 数据建模,但我很吃力。我正在寻找一些帮助来建立我现在拥有的东西。我觉得我的数据相当简单,但我并没有想到我应该怎么做才能适应 DynamoDB。

我有两种不同类型的数据。我有一个游戏对象和一个团队统计对象。一场比赛代表了那一周比赛的所有数据,而球队统计数据代表了给定球队每周的所有统计数据。

timeId 的格式为年-周(例如 2020-9)

我的访问模式是

1) Retrieve all games per timeId
2) Retrieve all games per timeId and by TeamName
3) Retrieve all games per timeId and if value = true

4) Retrieve all teamStats per timeId
5) Retrieve all teamStats by timeId and TeamName

我目前的建模尝试是:

PK: TeamName
SK: TimeId

这导致我有 2 个游戏副本,因为每个团队都有一个副本。它也只允许我通过 TimeId 扫描所有 teamStats。 GSI 之类的东西在这里有帮助吗?我想也许可以将 PK 更改为

PK: GA-${gameId} / TS-${teamId}
SK: TimeId

我只是很困惑,文档对我帮助不大。

查看您的访问模式,这是一种可能的 table 设计。我不确定它是否真的适用于您的 TimeId,尤其是 Local Secondary Index(请参阅下面的注释),但我希望这对您来说是一个好的起点。

# Table
-----------------------------------------------------------
pk       | sk                   | value | other attributes
-----------------------------------------------------------
TimeId   | GAME#TEAM{teamname}  | true  | ...
TimeId   | STATS#TEAM{teamname} |       | ...
GameId   | GAME                 |       | general game data (*)
TeamName | TEAM                 |       | general team data (*)
 
# Local Secondary Index
-------------------------------------------------------------------------------
pk from Table as pk | value from Table as sk | sk from Table + other attributes
-------------------------------------------------------------------------------
TimeId              | true                   | GAME#Team{teamname} | ...

有了这个 Table 和本地二级索引,您可以通过以下查询满足所有访问模式:

  1. 按timeId检索所有游戏:

    Query Table with pk: {timeId}

  2. 按 timeId 和 TeamName 检索所有游戏

    Query table with pk: {timeId}, sk: GAME#TEAM{teamname}

  3. 检索每个timeId的所有游戏,如果value = true

    Query LSI with pk: {timeId}, sk: true

  4. 检索每个 timeId 的所有 teamStats

    Query table with pk: {timeId}, sk: begins with 'STATS'

  5. 通过 timeId 和 TeamName 检索所有 teamStats

    Query table with pk: {timeId}, sk: STATS#TEAM{teamname}

*:我还添加了以下两项,因为我假设在某些情况下您还想检索有关特定游戏或团队的一般信息。这只是基于我的经验的假设,在您的情况下可能没有必要:

  1. 检索一般游戏信息

    Query table with pk: {GameId}

  2. 检索一般团队信息

    Query table with pk: {TeamName}

注意:我不知道 value = true 代表什么,但是要使二级索引在我的模型中起作用,您需要确保 [=20= 的每个组合] 并且 value = true 是唯一的。

要了解有关 single-table DynamoDB 设计的更多信息,请阅读 Alex DeBrie 的精彩文章 The What, Why, and When of Single-Table Design with DynamoDB