Amazon dynamodb 在DynamoDB中获取单个查询中的父项和子项

Amazon dynamodb 在DynamoDB中获取单个查询中的父项和子项,amazon-dynamodb,serverless,aws-serverless,dynamodb-queries,amazon-dynamodb-index,Amazon Dynamodb,Serverless,Aws Serverless,Dynamodb Queries,Amazon Dynamodb Index,我有以下一对多关系: Account 1--* User 科目包含全局科目级别信息,该信息是可变的 用户包含用户级别的信息,这些信息也是可变的 当用户登录时,他们需要帐户和用户信息。(此时我只知道UserId) 理想情况下,我希望设计模式,以便只需要一个查询。但是,如果不将帐户复制到每个用户中,并因此需要一些后台Lambda作业来将更改传播到所有用户对象中的帐户属性,我无法确定如何执行此操作——就记录而言,这似乎需要更多的资源使用(以及要维护的代码)而不是简单地规范化数据并在每个登录上有两个查

我有以下一对多关系:

Account 1--* User
科目
包含全局科目级别信息,该信息是可变的

用户
包含用户级别的信息,这些信息也是可变的

当用户登录时,他们需要
帐户
用户
信息。(此时我只知道
UserId

理想情况下,我希望设计模式,以便只需要一个查询。但是,如果不将
帐户
复制到每个
用户
中,并因此需要一些后台Lambda作业来将更改传播到所有
用户
对象中的
帐户
属性,我无法确定如何执行此操作——就记录而言,这似乎需要更多的资源使用(以及要维护的代码)而不是简单地规范化数据并在每个登录上有两个查询:fetch user,然后fetch account(在标识帐户的用户对象中使用FK)


是否可以设计一个模式,允许一个查询同时获取这两个数据,而不需要非事务性后台作业来传播更新?(事务性批量更新是不可能的,因为有超过25个用户。)如果不是,2-query是最好的/可接受的方法吗



我将集中讨论你问题中的一个角度——两个查询的想法。在许多情况下,这确实是一种可接受的方法,比其他方法更好。事实上,在许多NoSQL使用中,每个用户可见的请求都会导致两个以上的数据库请求。事实上,人们经常说,这就是NoSQL系统关心低尾延迟的原因(即,即使第99百分位延迟也应该低)

您没有说明为什么要避免使用2-query解决方案。您介绍的双查询实现有两个缺点:

  • 它的成本更高:您需要执行两个查询,而不是一个查询,成本(当读取小于4KB时)是单个读取的两倍
  • 如果您需要执行第一个查询,则延迟会加倍,只有这样才能执行第二个查询
  • 根据用例的更多细节,您可以使用一些技巧来解决这两个问题:

    对于延迟:您没有说明应用程序中的“用户id”是什么。如果它是某种唯一的数字标识符,可能可以设置为直接从用户id确定帐户id,而无需查表(例如,用户id的第一位是帐户id)。如果是这种情况,您可以同时启动两个查找,而不是将延迟增加一倍。成本仍将是原来的两倍,但延迟不会增加


    成本:如果每个帐户有大量用户(你说有超过25个-我不知道是否更多),缓存帐户数据可能很有用,因此不是每个用户查找都需要再次读取帐户数据-它可能经常被缓存。如果账户信息很少发生变化,而且一致性也不是什么大问题(我不知道是否是…),那么您也可以通过对账户信息进行“最终一致性”读取来解决,这需要花费常规“一致性”读取的一半。

    我将集中讨论您问题中的一个角度——两个查询的想法。在许多情况下,这确实是一种可接受的方法,比其他方法更好。事实上,在许多NoSQL使用中,每个用户可见的请求都会导致两个以上的数据库请求。事实上,人们经常说,这就是NoSQL系统关心低尾延迟的原因(即,即使第99百分位延迟也应该低)

    您没有说明为什么要避免使用2-query解决方案。您介绍的双查询实现有两个缺点:

  • 它的成本更高:您需要执行两个查询,而不是一个查询,成本(当读取小于4KB时)是单个读取的两倍
  • 如果您需要执行第一个查询,则延迟会加倍,只有这样才能执行第二个查询
  • 根据用例的更多细节,您可以使用一些技巧来解决这两个问题:

    对于延迟:您没有说明应用程序中的“用户id”是什么。如果它是某种唯一的数字标识符,可能可以设置为直接从用户id确定帐户id,而无需查表(例如,用户id的第一位是帐户id)。如果是这种情况,您可以同时启动两个查找,而不是将延迟增加一倍。成本仍将是原来的两倍,但延迟不会增加


    成本:如果每个帐户有大量用户(你说有超过25个-我不知道是否更多),缓存帐户数据可能很有用,因此不是每个用户查找都需要再次读取帐户数据-它可能经常被缓存。如果帐户信息很少更改,而且一致性也不是什么大问题(我不知道是否是…),您也可以对帐户信息进行“最终一致性”读取,这将花费常规“一致性”读取的一半。

    我想到的一种有效获取父项+子项的方法,考虑到子项ID,就是让子ID包含父ID。然后,给定任何子ID,可以执行“batchGetItem”调用,将两个PK传入。虽然这仍然与2x查询的成本相同,但它实际上与单个查询一样快,因为“batchGetItem”将并行获取项。。。所以你只需要等待最长的查询。。。但你所做的只是一个值得“等待”的查询。假设您处于项目的开始阶段/可以选择ID的生成方式。我想到的一种有效获取父+子ID的方法是,给定子ID,让子ID包含父ID。然后,给定任何子ID,可以执行“batchGetItem”调用,将两个PK传入。虽然这仍然与2x查询的成本相同,但它实际上与给定的单个查询一样快