在DynamoDB中设计查找表

时间:2018-07-27 22:54:14

标签: amazon-dynamodb

我在使用dynamodb设计查询表时遇到了一些问题,而没有遇到GSI问题。

我有一个对象U,该对象具有4个(感兴趣的)属性。 Id,A,B和C。我有另一个对象T,它具有2个(感兴趣的)属性Id和一个U.Id列表。

我需要创建一个DynamoDB表,可以在其中进行快速查找,例如。

给出T.Id,给我所有具有A的U对象,或给定T.Id,给我所有具有B的连接的U对象。最后给定U.Id,给我具有U的T.Id。列表中的ID。

我在想类似的东西

| T.Id | Sort Key | U.Id | U.A | U.B | U.C |
| T1   | U1       | U1   | abc | rew | bgt |
| T1   | U2       | U2   | bgf | red | bcs |
| T2   | U3       | U3   | abc | rew | bgt |

其中T.Id是主键,排序键是U.Id。 然后是关于U.ID,U.A,U.B和U.C的GSI。

这种方法现在应该可以使用,但是我仅限于5 GSI,而且我知道以后会在U上添加更多属性。 T的清单中可能有2000个U.Id。

我应该如何进行DynamoDB设计以实现最快的查找并且不遇到GSI限制的问题?

像给所有U.Id指定T.Id,UA和UB这样的用例很容易支持,但不是必需的,我可以要求此表的用户进行多个调用的交集。

2 个答案:

答案 0 :(得分:2)

我的解决方案的想法是花费空间复杂度以减少时间复杂度。

创建一个表,哈希键应为U.id或T.id,其前缀为“ U”。或“ T.”,然后我们将范围键称为“查找”。如果要将T.Id的查找设置为U.Id,则Lookup列应为合成键,查找键的前缀为“ id。”;如果要将T.Id查找为A,则查找键的前缀为合成键。是“ A”。后缀是U.Id,与B和C相同。
属性A,B,C只应存储在ID和查找都是U.Id值的记录中

要允许U.Id引用回T.Id,应为查找列创建GSI。

|Id  |Lookup     |Attributes|
+----+-----------+----------+
|U.Id|U.Id       |A,B,C     |
|T.Id|id.value   |          |
|T.Id|A.value:Id |          |
|T.Id|B.value:Id |          |
|T.Id|C.value:Id |          |
  1. 给出T.Id(值为'tid'),给我所有具有A的U对象(值为'a') SELECT 'Lookup' FROM table WHERE Id = T.tid & Lookup.beginsWith('A.a'); 然后,我们可以通过用':'分割查询的值来获取所有U的ID。然后使用批处理获取所有U的值
  2. 与B和C的想法相同
  3. 最后给定的U.Id(值为'uid'),请给我一个T.Id,该列表中包含U.Id。
    SELECT 'Id' FROM table WHERE Lookup = id.uid;
    然后,您有了T.Id

如果您有任何问题,希望我的回答可以为您提供帮助。

通知:我编写的SQL只是伪代码,仅供您参考。

答案 1 :(得分:1)

您所描述的是一对多关系。阅读有关如何在NOSQL存储中建立一对多关系的模型。

为了使这个摘要不那么抽象,我将假设u = user和t = team。一个团队可以拥有许多用户。一个用户只能在一个团队中。

对此建模的方法是拥有两个表-用户表和团队表。请注意,如果团队没有属性,则仅用户表就足够了。

用户表:

分区密钥:UserId

属性:A

属性:B

属性:C

属性:TeamId

用户表GSI:

分区密钥:团队ID

团队表:

分区键:TeamId

属性:X

给出T.Id,给我所有具有A的U对象

使用GSI查询用户表,分区键= TeamId,在A上使用filterexpression

给出T.Id,给我所有具有B的已连接U对象

使用GSI查询用户表,分区键= TeamId,在B上使用filterexpression

最后给定的U.Id,给我一个在列表中包含U.Id的T.Id。

使用主分区键在User表上使用GetItem

@ Yu-Huang描述的解决方案是一个图节点实现。您可以在https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-adjacency-graphs.html

的DynamoDB上下文中阅读它。

我不建议此实现。它适用于多对多关系,并且在不需要时会增加很多复杂性。