问题描述
我有以下一对多关系:
Account 1--* User
Account
包含可变的全局帐户级别信息。
User
包含用户级别的信息,该信息也是可变的。
用户登录时,他们同时需要Account
和User
信息。 (目前我只知道UserId
。
理想情况下,我希望设计架构以使单个查询是必需的。但是,如果不将Account
复制到每个User
中并因此需要一些背景Lambda作业在所有Account
对象之间传播对User
属性的更改,我无法确定如何执行此操作- -记录下来,这似乎比简单地标准化数据并在每次登录时有2个查询要更多的资源使用(和要维护的代码):获取用户,然后获取帐户(使用用户对象内部的FK来标识帐户)帐户)。
是否可以设计一个允许一个查询同时获取 且不需要非事务性后台作业来传播更新的架构? (因为有25个以上的用户,所以无法进行事务批处理更新。)如果不是,那么2查询的想法是最好的/可接受的方法吗?
解决方法
我将集中讨论您的问题中的一个问题-2查询的想法。在许多情况下,这确实是一种可接受的方法,比其他方法更好。实际上,在许多NoSQL用法中,每个用户可见的请求都会导致两个以上的数据库请求。实际上,经常有人说这就是NoSQL系统关心低尾部延迟的原因(即,即使第99个百分位数的延迟也应较低)。
您没有说为什么要避免2查询解决方案。您介绍的2查询实现有两个缺点:
- 成本更高:您需要执行两个查询而不是一个查询,因此成本(当读取小于4 KB时)是单个读取的两倍。
- 如果您需要执行第一个查询,则延迟会加倍,只有这样才能执行第二个查询。
根据用例的更多详细信息,可以使用一些技巧来解决这两个问题:
对于延迟:您没有说出应用程序中的“用户ID”是什么。如果它是某种唯一的数字标识符,则可以将其设置为可以直接从用户ID确定帐户ID,而无需进行表查找(例如,用户ID的前几位是帐户ID)。在这种情况下,您可以同时启动两个查找,而不会使延迟增加一倍。代价仍然是两倍,但不是延迟。
有关费用:如果每个帐户有大量用户(您说的用户数超过25-我不知道这个数目是否很多),则缓存帐户数据可能很有用,因此并不是每个用户查询都需要再次读取帐户数据-它可能经常被缓存。如果帐户信息很少更改并且一致性不是什么大问题(我不知道它是否...),您还可以通过“最终一致性”读取帐户信息来完成-花费一半的时间常规的“一致”阅读。