有没有更好的方法来设计这个不需要重复数据的 DynamoDB table?
Is there a better way to design this DynamoDB table that doesn't require duplication of data?
我有一个相对简单的数据模型,我想将其存储在 DynamoDB 中。然而,由于不同的访问模式,选择主键和排序键一直很困难。我找到了一种以适合我的模式的方式存储数据的方法,但需要多行具有基本相同的数据。这让我觉得我错过了什么。
场景:
该应用程序为我们的客户管理记录,这些客户拥有大量 IOT 设备,随着时间的推移不断报告其状态。
数据:
customer_id, device_id, timestamp, device_state, device_manufacturer
访问模式:
- 获取与
customer_id
关联的每个唯一 device_id
值的最新记录。
- 获取
customer_id
的最新记录,而不考虑 device_id
- 获取特定
device_id
、customer_id
对的 timestamp
排序值。
第 2 点和第 3 点一开始看起来很简单。 table,其中主键为 customer_id
,排序键为 timestamp
,GSI 的主键为 device_id
,排序键为 timestamp
.有了这个设置,我不知道如果不在 table 上进行非常昂贵的扫描和过滤操作,我将如何实现第 1 点。我希望 table 变得非常大。
我的解决方案
| primary key | sort key |
| -------------------------------- | ---------------- |
| "customer_" + customer_id | timestamp |
| "device_" + device_id | timestamp |
| "latest_device_" + customer_id | device_id |
每个设备记录使用不同的密钥策略更新 3 次。使用第一个和第二个键创建一个新记录,并为第三个键更新该行。上面第1点使用“latest_device_”+customer_id键,第2点使用“customer_”+customer_id,第3点使用“device_”+device_id键。
这有效,但感觉很恶心。这让我觉得我错过了 Dynamo 的核心概念或其他一些让我不必重复数据的关键点。
有没有办法设计我的 table 来避免这种数据重复,同时仍然允许我实现 3 种访问模式?
nosql 设计的第一条规则...重复是预期的。
其次,使用 DDB,您不必总是自己进行复制。 DDB 将通过全球二级索引 (GSI) 为您完成。
第三条规则,了解您的访问要求。 (干得好!)
这是我要考虑的(假设 cust/dev 没有两个时间戳相同)
table
哈希键:“customerId#deviceId”
排序键:“2021-07-08T15:55:34Z”
属性:{customer_id、device_id、时间戳、device_state、device_manufacturer}
还有一个 GSI
哈希:customer_id
排序:时间戳
那就够了
2. 获取 customer_id 的最新记录,而不考虑 device_id
--> 查询(gsi,hk="customerId")
3. 获取特定 device_id、customer_id 对的时间戳排序值。
--> 查询(table,hk="customerId#deviceId")
棘手的是
- 获取与 customer_id 关联的每个唯一 device_id 值的最新记录。
我希望有一个客户记录(可能通过 DDB 流 + lambda 维护),其中包含该客户每个设备的最新记录数组。假设该列表足够小,可以合理地放入 DDB 记录中。基本上将此视为实际记录的 aggregation 类型。
我有一个相对简单的数据模型,我想将其存储在 DynamoDB 中。然而,由于不同的访问模式,选择主键和排序键一直很困难。我找到了一种以适合我的模式的方式存储数据的方法,但需要多行具有基本相同的数据。这让我觉得我错过了什么。
场景: 该应用程序为我们的客户管理记录,这些客户拥有大量 IOT 设备,随着时间的推移不断报告其状态。
数据:
customer_id, device_id, timestamp, device_state, device_manufacturer
访问模式:
- 获取与
customer_id
关联的每个唯一device_id
值的最新记录。 - 获取
customer_id
的最新记录,而不考虑device_id
- 获取特定
device_id
、customer_id
对的timestamp
排序值。
第 2 点和第 3 点一开始看起来很简单。 table,其中主键为 customer_id
,排序键为 timestamp
,GSI 的主键为 device_id
,排序键为 timestamp
.有了这个设置,我不知道如果不在 table 上进行非常昂贵的扫描和过滤操作,我将如何实现第 1 点。我希望 table 变得非常大。
我的解决方案
| primary key | sort key |
| -------------------------------- | ---------------- |
| "customer_" + customer_id | timestamp |
| "device_" + device_id | timestamp |
| "latest_device_" + customer_id | device_id |
每个设备记录使用不同的密钥策略更新 3 次。使用第一个和第二个键创建一个新记录,并为第三个键更新该行。上面第1点使用“latest_device_”+customer_id键,第2点使用“customer_”+customer_id,第3点使用“device_”+device_id键。
这有效,但感觉很恶心。这让我觉得我错过了 Dynamo 的核心概念或其他一些让我不必重复数据的关键点。
有没有办法设计我的 table 来避免这种数据重复,同时仍然允许我实现 3 种访问模式?
nosql 设计的第一条规则...重复是预期的。
其次,使用 DDB,您不必总是自己进行复制。 DDB 将通过全球二级索引 (GSI) 为您完成。
第三条规则,了解您的访问要求。 (干得好!)
这是我要考虑的(假设 cust/dev 没有两个时间戳相同)
table
哈希键:“customerId#deviceId”
排序键:“2021-07-08T15:55:34Z”
属性:{customer_id、device_id、时间戳、device_state、device_manufacturer}
还有一个 GSI
哈希:customer_id
排序:时间戳
那就够了
2. 获取 customer_id 的最新记录,而不考虑 device_id
--> 查询(gsi,hk="customerId")
3. 获取特定 device_id、customer_id 对的时间戳排序值。
--> 查询(table,hk="customerId#deviceId")
棘手的是
- 获取与 customer_id 关联的每个唯一 device_id 值的最新记录。
我希望有一个客户记录(可能通过 DDB 流 + lambda 维护),其中包含该客户每个设备的最新记录数组。假设该列表足够小,可以合理地放入 DDB 记录中。基本上将此视为实际记录的 aggregation 类型。