我在使用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这样的用例很容易支持,但不是必需的,我可以要求此表的用户进行多个调用的交集。
答案 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 | |
SELECT 'Lookup' FROM table WHERE Id = T.tid & Lookup.beginsWith('A.a');
然后,我们可以通过用':'分割查询的值来获取所有U的ID。然后使用批处理获取所有U的值SELECT 'Id' FROM table WHERE Lookup = id.uid;
如果您有任何问题,希望我的回答可以为您提供帮助。
通知:我编写的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上下文中阅读它。我不建议此实现。它适用于多对多关系,并且在不需要时会增加很多复杂性。