我是DynamoDB技术的新手,但不是NoSQL的新手(我已经使用Firebase完成了一些项目)。
请阅读DynamoDB的最佳实践是每个应用程序一张表,我一直在努力设计1对N关系。
我有这个实体(pseudo-json):
{
machineId: 'HASH_ID'
machineConfig: /* a lot of fields */
}
machineConfig
在每台计算机上都是唯一的,并且很少更改,只能由管理人员更改(此处没有一致性问题)。
问题是我必须管理来自每台机器的传感器的数据日志。日志描述为:
{
machineId: 'HASH_ID',
sensorsData: [
/* Huge list of: */
{ timestamp: ..., data: /* lot of fields */ },
...
]
}
我想将machineConfig
放在一个地方。日志列表不能插入到计算机实体中,因为它是随时间推移而连续获取的数据流。
此外,我不知道哪个可能是组合键,分区键显然是machineId
,但是订购键呢?
如何在考虑数据潜在维度的情况下设计这种关系?
答案 0 :(得分:2)
您可以使用1张桌子来完成此操作。主键可以是(machineId, sortKey)
,其中machineId
是分区键,而sortKey
是将用于覆盖这两种情况的字符串属性。您可能想出一个更好的名字。
要存储machineConfig
,您将插入具有主键(machineId, "CONFIG")
的项目。 sortKey
属性将具有常量值CONFIG
。
要存储sensorsData
,可以使用timestamp
作为sortKey
的值。您将为每个传感器数据插入一个新项目。您可以将timestamp
存储为字符串(以自纪元,ISO8601等以来的时间为准)
然后要查询有关机器的所有信息,您将只指定machineId
分区键来运行Dynamo查询-这将返回许多项,包括machineConfig
和传感器数据。
要仅查询machineConfig
,您将运行Dynamo查询,并指定machineId
分区键和常量CONFIG
作为sortKey
值
要查询传感器数据,可以为sortKey
指定确切的时间戳或时间戳范围。如果需要通过其他值查询传感器数据,则此设计可能无法正常工作。
编辑以回答后续问题:
您将不得不借助过滤器进行扫描,以返回所有带有machineId
和machineConfig
的计算机。如果最终插入大量传感器数据,那么执行此操作将是非常昂贵的操作,因为Dynamo将查看表中的每个项目。如果您需要这样做,则有两种选择。
如果没有很多机器,则可以插入带有主键的项,例如("MACHINES", "ALL")
和所有machineIds
的列表。您将查询该键以获取machineIds
的列表,然后进行一堆查询(或批量获取)以检索所有相关的machineConfigs
。但是,由于Dynamo的最大项目大小为400KB,因此您可能无法全部容纳它们。
如果有太多机器无法放入一个项目中,则可以稍微改变上述方法,并以("MACHINES", $machineIdSubstring)
作为主键,并在每个排序键下存储machineIds
的块。例如,所有以0开头的machineIds
进入("MACHINES", "0")
。然后,您将通过每个主键0-9进行查询,构建所有machineIds
的列表,并如上所述查询每台计算机。
或者,您不必将所有内容都放在一张表中-这只是适合许多用例的准则。如果有太多机器无法容纳少于400KB,但没有成千上万的计算机,并且您不想一直查询所有这些计算机,则可以有一个单独的表machineId
和{{ 1}},您可以在必要时进行扫描。