首页 > 解决方案 > 有没有更好的方法来设计这个不需要重复数据的 DynamoDB 表?

问题描述

我有一个想要存储在 DynamoDB 中的相对简单的数据模型。但是,由于访问模式不同,选择主键和排序键一直很困难。我找到了一种以适合我的模式的方式存储数据的方法,但需要多行具有基本相同的数据。这让我觉得我错过了什么。

场景: 该应用程序为我们的客户管理记录,这些客户拥有大量 IOT 设备,随着时间的推移一致地报告其状态。

数据:

customer_id, device_id, timestamp, device_state, device_manufacturer

访问模式:

  1. device_id获取与 a 关联的每个唯一值的最新记录customer_id
  2. 获取最新customer_id记录device_id
  3. 获取timestamp特定device_id,customer_id对的排序值。

第 2 点和第 3 点一起看起来很简单。customer_id主键为且排序键为的表,主键为timestampGSI,device_id排序键为timestamp。有了这个设置,我不知道如果不对表进行非常昂贵的扫描和过滤操作,我将如何实现第 1 点。我希望这张桌子会变得非常大。

我的解决方案

| 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 的核心概念或其他一些让我不必复制数据的关键点。

有没有办法设计我的表来避免这种数据重复,同时仍然允许我实现 3 种访问模式?

标签: database-designnosqlamazon-dynamodb

解决方案


First rule of nosql design...duplication is expected.

Secondly, with DDB you don't have to always do the duplication yourself. DDB will do it for you via Global Secondary Indexes (GSI).

Third rule, know your access requirements. (Good job!)

Here's what I'd consider (assuming no two timestamps for cust/dev are the same)
table
hash-key : "customerId#deviceId"
sort-key : "2021-07-08T15:55:34Z"
attributes: {customer_id, device_id, timestamp, device_state, device_manufacturer}

And a GSI with
hash: customer_id
sort: timestamp

That would cover
2. Get the most recent records for a customer_id regardless of device_id
--> Query(gsi,hk="customerId")
3. Get timestamp sorted values for a specific device_id, customer_id pair.
--> Query(table,hk="customerId#deviceId")

The tricky one is

  1. Get the most recent record for each of the unique device_id values associated with a customer_id.

I'd look having a CUSTOMER record (possibly maintained via DDB streams+lambda) containing an array of the most recent records for each device for that customer. Assuming the list is small enough to fit reasonably in a DDB record. Basically considering this as a type of aggregation of the actual records.


推荐阅读