首页 > 解决方案 > DynamoDB - 设计一对多关系

问题描述

我是 DynamoDB 技术的新手,但不是 NoSQL(我已经使用 Firebase 完成了一些项目)。

读到 DynamoDB 最佳实践是每个应用程序一个表 我一直很难设计我的 1 对 N 关系。

我有这个实体(伪json):

{
   machineId: 'HASH_ID'
   machineConfig: /* a lot of fields */
}

AmachineConfig对于每台机器都是唯一的,并且很少更改并且只能由管理人员更改(此处没有一致性问题)。

问题是我必须管理来自每台机器传感器的数据日志。日志描述为:

{
  machineId: 'HASH_ID',
  sensorsData: [
    /* Huge list of: */
    { timestamp: ..., data: /* lot of fields */ },
    ...
  ]
}

我想把我machineConfig的放在一个地方。日志列表不能插入机器实体,因为它是随时间推移而获取的连续数据流。

此外,我不明白哪个可能是复合键,分区键显然是machineId,但是顺序键呢?

考虑到数据的潜在维度,如何设计这种关系?

标签: databaseamazon-web-servicesamazon-dynamodb

解决方案


你可以用 1 张桌子做到这一点。主键可能是分区键在(machineId, sortKey)哪里,并且是一个字符串属性,将用于覆盖这两种情况。你可能会想出一个更好的名字。machineIdsortKey

要存储,machineConfig您将插入一个带有主键的项目(machineId, "CONFIG")。该sortKey属性将具有常量值CONFIG

要存储sensorsData你可以使用timestamp作为sortKey值。您将为每条传感器数据插入一个新项目。您可以将其存储timestamp为字符串(作为纪元以来的时间、ISO8601 等)

然后要查询有关机器的所有内容,您将运行仅指定machineId分区键的 Dynamo 查询 - 这将返回许多项目,包括machineConfig和传感器数据。

要仅查询,machineConfig您将运行 Dynamo 查询,指定machineId分区键和常量CONFIG作为sortKey

要查询传感器数据,您可以为sortKey. 如果您需要通过其他值查询传感器数据,那么这种设计可能无法正常工作。

编辑以回答后续问题:

您将不得不求助于带有过滤器的扫描来返回所有带有它们的机器machineIdmachineConfig. 如果您最终插入了大量传感器数据,那么这将是一项非常昂贵的操作,因为 Dynamo 将查看表中的每个项目。如果你需要这样做,你有几个选择。

如果没有很多机器,您可以插入一个带有主键的项目,如("MACHINES", "ALL")所有machineIds. 您将查询该键以获取 的列表machineIds,然后您将执行一堆查询(或批量获取)以检索所有相关的machineConfigs. 但是,由于 Dynamo 项目的最大大小为 400KB,因此您可能无法全部容纳它们。

如果有太多机器无法容纳一个项目,您可以稍微改变上述方法并将其("MACHINES", $machineIdSubstring)作为主键并machineIds在每个排序键下存储块。例如,所有machineIds以 0 开头的都进入("MACHINES", "0"). 然后您将按每个主键 0-9 进行查询,构建所有列表machineIds并如上所述查询每台机器。

或者,您不必将所有内容都放在一张表中 - 它只是适用于许多用例的指南。如果有太多机器无法容纳小于 400 KB,但没有数万台,并且您不会一直尝试查询所有机器,则可以有一个单独的表,machineIdmachineConfig在必要时进行扫描.


推荐阅读