我正在构建一个应用程序,其中两个用户可以相互连接,我需要在DynamoDB表中存储该连接(例如友谊)。基本上,连接表有两个字段:
我想在userIdB上添加一个索引来查询这两个字段。我应该存储一个记录(ALICE,BOB)或两个记录(ALICE,BOB; BOB,ALICE)的连接吗?第一个选项需要一个写操作和更少的空间,但我必须查询两次才能获得用户的所有连接。第二个选项需要两个写操作和更多空间,但我只需要为userId查询一次。
用户表包含姓名和电子邮件等详细信息:
在我的应用中,我想在列表视图中显示某个用户的所有连接以及用户详细信息。这意味着我有两个选择:
那么什么是更好的解决方案,还是我可能忽略了其他任何优点/缺点?
在对NoSQL数据库的友情表进行一些谷歌研究之后,我发现了以下两个链接:
NoSQL Design Patterns for Relational Data
第一个链接建议使用两条记录以双向方式存储连接(或友谊),因为它使查询更容易,更快:
Connections:
1 userIdA userIdB
2 userIdB userIdA
第二个链接建议将重复数据的子集(“摘要”)保存到表中,只需一个查询就可以更快地读取它。这意味着将用户详细信息也保存到连接表中,并将userIds保存到用户表的属性中:
Connections:
# userIdA userIdB userDetails status
1 123 456 { userId: 456, name: "Bob" } connected
2 456 123 { userId: 123, name: "Alice" } connected
Users:
# userId name connections
1 123 Alice { 456 }
2 456 Bob { 123 }
此数据库模型使查询连接非常容易,但如果某些用户详细信息可能更改,则似乎很难更新。另外,我不确定我是否需要再次在用户表中使用userId,因为我可以轻松查询userId。
您如何看待该数据库模型?
答案 0 :(得分:2)
通常,nosql数据库通常与几个假设相结合:
最终的一致性是可以接受的。也就是说,如果在更新期间某些中间答案是对的,那么它在应用程序设计中通常是可以接受的。也就是说,如果爱丽丝成为鲍勃的朋友几秒钟就可以了,如果爱丽丝鲍勃的朋友是#34;那就好了。返回true,而#34;是Bob Alice的朋友"返回false
表现很重要。如果你正在使用nosql,那通常是因为性能对你很重要。它也几乎可以肯定,因为您关心最常发生的操作性能。 (你可能会遇到一些问题,其中一些不常见的操作的性能如此糟糕以至于你无法做到;在这种情况下,nosql通常不是答案)
您愿意减少不常见的操作以提高常见操作的性能。
那么,这是如何适用于您的问题的。首先,它表明答案最终取决于绩效。也就是说,无论人们在这里说什么,正确的答案取决于你在实践中观察到的。您可以尝试多种选项,看看您得到的结果。
关于您列举的具体选项。
假设性能足以让nosql成为您应用程序的合理解决方案,那么几乎可以肯定的是查询而不是更新您关心的性能。如果您使更新更慢,更昂贵,您可能会很高兴,以便查询可以更快。这就是重点。
您可以在带外处理更新 - 这最终的一致性可能对您有用。您可以将更新操作提交到SQS队列,而不是在页面加载期间处理它们。因此,如果有人单击确认朋友按钮,您可以将请求排队以实际更新数据库。即使这涉及重建用户行,重建朋友行,甚至更新他们有多少朋友的计数,也没关系。
在每个方向存储朋友行可能是有意义的,因此您只需要一个查询。
将您通常显示在友谊行中重复的朋友列表中的用户信息(如姓名和图片)存储可能是有意义的。请注意,只要名称或图片发生变化,您就需要更新所有这些行。
不太清楚将朋友存储在用户表中是有道理的。这可能会变得很大。此外,保证最终的一致性可能很棘手。考虑如果您正在处理两个用户的更新,会发生什么?友谊在同一时间。一旦尘埃落定,你就不会感到不一致,这一点非常重要。
每当您有非规范化数据(如在每个方向上复制行)或将用户信息复制到友谊表中时,您都需要某种方法来重新验证和修复数据。您希望编写的代码可以在后台扫描您的系统,查找由错误或崩溃的活动引起的不一致情况并进行修复。
答案 1 :(得分:1)
我建议您在表格中包含以下字段:
此结构可确保数据的一致性。