AWS DynamoDB表设计:存储两个用户ID和详细信息



我正在构建一个应用程序,两个用户可以彼此连接,我需要在DynamoDB表中存储该连接(例如友谊(。基本上,连接表有两个字段:

  • Userida(Hash键(
  • UserIdb(sort键(

我正在考虑在UserIdB上添加索引以在两个字段上查询。我应该存储一个连接的连接(爱丽丝,鲍勃(还是两个记录(爱丽丝,鲍勃;鲍勃,爱丽丝(?第一个选项需要一个写操作和更少的空间,但是我必须查询两次以获取用户的所有连接。第二个选项需要两个写操作和更多空间,但我只需要查询一次用户ID。

用户表详细信息诸如姓名和电子邮件:

  • 用户ID(哈希密钥(
  • 名称(sort键(
  • 电子邮件

在我的应用程序中,我想在ListView中显示具有用户详细信息的某个用户的所有连接。这意味着我有两个选择:

  1. 将连接用户的用户详细信息存储在连接表中,例如在该表中添加两个名称字段。这很快,但是如果用户名更改(从Facebook检索名称和电子邮件(,详细信息无效,我需要更新所有条目。
  2. 查询每个用户ID的用户详细信息,其中批处理读取多个项目的请求。这可能会更慢,但是我总是有最新的用户详细信息,并且不需要将它们存储在连接表中。

那么,更好的解决方案是什么,或者我可能会忽略的其他优点/缺点?

编辑

在有关NOSQL数据库的Google进行了一些有关友谊表的研究之后,我找到了以下两个链接:

Facebook如何为每个用户维护朋友列表?它是否为每个用户维护单独的表?

NOSQL设计模式的关系数据

第一个链接建议用两个记录将连接(或友谊(沿两个方向存储,因为它使查询更容易,更快:

Connections:
    1 userIdA    userIdB
    2 userIdB    userIdA

第二个链接建议将重复数据的子集(摘要(保存到表中,以更快地使用一个查询来读取它。这意味着将用户详细信息也保存到连接表中,并将用户ID保存到用户表的属性中:

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 }   

此数据库模型使查询连接非常容易,但是如果某些用户详细信息可能会更改,似乎很难更新。另外,我不确定是否需要在用户表中再次需要用户ID,因为我可以轻松查询用户ID。

您如何看待该数据库模型?

通常,NOSQL数据库通常与几个假设相结合:

  • 最终的一致性是可以接受的。也就是说,如果在更新中,某些中间答案不正确,则通常可以接受应用程序设计。也就是说,如果爱丽丝成为鲍勃的朋友时,如果"是爱丽丝·鲍勃的朋友"返回,而"鲍勃·爱丽丝的朋友"返回false false

  • ,那可能还可以。
  • 性能很重要。如果您使用的是NOSQL,则通常是因为性能对您很重要。这几乎可以肯定的是,您关心最常见的操作表现。(您可能会遇到问题,而某些不常见操作的性能是如此糟糕,以至于无法做到; NOSQL通常不是这种情况下的答案(

  • 您愿意使罕见的操作较慢以提高共同操作的性能。

因此,这如何适用于您的问题。首先,这表明答案最终取决于性能。也就是说,无论人们在这里怎么说,正确的答案都取决于您在实践中观察到的内容。您可以尝试多个选项并查看获得的结果。

关于您列举的特定选项。

  • 假设性能足以使NOSQL是您应用程序的合理解决方案,那么几乎可以肯定的是查询而不是更新您关心的性能。如果您的更新速度较慢,更昂贵,以便查询更快,您可能会很高兴。这是一个重点。

  • 您可能可以从乐队中处理更新 - 最终一致性可能对您有用。您可以将更新操作提交给SQS队列,而不是在页面加载期间处理它们。因此,如果有人单击确认的朋友按钮,您可以将请求排队以实际更新数据库。即使这涉及重建他们的用户行,重建朋友行,甚至更新了他们有多少个朋友的计数。

  • 在每个方向上存储一个朋友行确实很有意义,因此您只需要一个查询。

  • 存储通常在友谊行中重复的朋友列表中显示的用户信息(例如名称和图片(确实很有意义。请注意,每当名称或图片更改时,都需要去更新所有这些行。

  • 很清楚将朋友存储在用户表中是有道理的。那可能会变得很大。而且,保证最终的一致性可能很棘手。考虑一下如果您同时处理两个用户的友谊,会发生什么。一旦所有灰尘都安定下来,就不会使您不一致很重要。

  • 每当您拥有非归一化数据(例如在每个方向复制行(或将用户信息复制到友谊表中时,您都需要某种方法来重新验证和修复数据。您想编写的代码可以在后台扫描您的系统是否因错误或崩溃活动引起的不一致之处并进行修复。

我建议您在表中有以下字段:

  • userId (hash键(
  • name (sort键(
  • 电子邮件
  • Connections (逗号分隔或用户ID的数组假设您有多个连接的用户(

这种结构可以确保您的数据一致性。

最新更新