当前位置: 首页 > 知识库问答 >
问题:

如何设计每个应用程序只有一个DynamoDB表的关键模式?

施自珍
2023-03-14

根据DynamoDB文件:https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-general-nosql-design.html

“在DynamoDB应用程序中,您应该维护尽可能少的表。大多数设计良好的应用程序只需要一个表。”

但是根据我的经验,由于分区键设计,你总是不得不做相反的事情。

让我们考虑下一个情况。我们有几个用户角色,例如,“管理员”、“经理”、“工人”。管理员通常的工作流程是CRUD管理器数据,其中读取操作不是获取一个管理器,而是获取所有管理器列表。经理也是如此——他CRUDs工人数据。对于这两种情况,我们只有两种密钥使用场景:

  • 获取所有项目的列表(项目键不重要)
  • 使用某个特定项的全键处理它。

当然,我们应该有均匀分布的分区键(正如文档强调的那样),因此我们不能为它选择用户角色,而应该使用用户id。由于我们已经有一些随机id作为分区键,我们根本不需要排序键,因为它根本不起作用-我们已经通过使用分区键部分来访问一个用户。在这一点上,我们意识到用户id对于CUD操作来说就像一个符咒,但是对于每个R操作,我们需要扫描所有的表,然后按用户角色过滤结果,这是无效的。如何改进这一点?非常自然-让我们为每个用户类型创建自己的表!然后,我们将从管理API扫描经理列表,从经理API扫描工作人员列表。

我使用DynamoDB几乎一年,仍然无法获得它。对我来说,现实是,对于现实生活中的场景,排序键是你永远不能使用的东西(我唯一真正使用它的情况是访问像“协议”这样同时属于不同类型的两个用户的项目,所以主要的键值为{partion:"Manager Id",排序:"userId"},二级全局索引为{分区:"userId",排序:"Manager Id"},因此我可以有效地查询所有特定的管理器协议列表或所有特定的用户协议列表,仅提供相应的管理器或用户ID用于查询。该方法在doc中讨论:https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-adjacency-graphs.html)。

我觉得我根本不懂这个概念。对于所提供的示例,对于这两种用户类型,仅使用一个DynamoDB表的有效方法是什么?

共有2个答案

董胡非
2023-03-14

您可以使用类似的模式

user_id, role, <other columns>

哪里

  • 用户id=散列键

这样,您可以通过查询GSI来读取和获取所有经理的列表

使用GSI,DynamoDb创建另一个表并维护它,因此您不需要维护多个表。

如果你有任何问题,请告诉我

杜砚
2023-03-14

在这种情况下,听起来您需要的是一个全局二级索引(https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html)其中分区键是用户角色。这样,您可以通过该UserRoleIndex查询具有特定角色的所有用户,并在用户ID上的排序键的帮助下,在该角色中挑出一个特定用户。

或者,如果您从头开始创建一个新表,您甚至可能不需要索引(除非您在删除用户时不知道用户的角色)。您可以使用“复合主键”(https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.PrimaryKey)其中,分区键和排序键与我上面建议的索引中的相同。

使用您在问题中使用的相同符号,我建议使用{partition:“userRole”,sort:“userId”}

DynamoDB有时很难理解,在某些情况下,传统的SQL数据库更有意义。AWS re: Invent 2018的这段视频很好地理解了两者的区别:https://www.youtube.com/watch?v=HaEPXoXVf2k

不过,在您的情况下,看起来您有一个非常清晰的访问模式,因此DDB适合您。

 类似资料:
  • 问题内容: 我读到每个应用程序都在自己的JVM中运行。为什么会这样呢?他们为什么不让一个JVM运行2个或更多应用程序? 我说的是通过公共静态void main(String [])方法启动的应用程序…) 问题答案: (我假设您正在谈论通过方法启动的应用程序…) 理论上,您可以在JVM中运行多个应用程序。实际上,它们可以以各种方式相互干扰。例如: JVM具有一组System.in/out/err,一

  • 我有一个java应用程序,它在运行时会产生另一个JVM。然而,我想使用jpack打包我的应用程序,它运行得很好。但是在运行时,当我的应用程序尝试使用调用下一个JVM时 我必须知道,应用程序是使用定制的JVM启动的,并且没有像“java”这样的命令。所以我得到的错误是这个java。无法执行getAbsolutePath()。 如果没有java可执行文件,我的应用程序如何在单独的进程中运行另一个jar

  • 我不确定这是否是问这个问题的正确地方。 我是dynamodb的新手,正在尝试创建一个小型web应用程序。我已经阅读了这里的最佳实践http://docs.amazonwebservices.com/amazondynamodb/latest/developerguide/BestPractices.html 我的桌子将是: 建筑物 租户(一栋建筑可以有尽可能多的租户,由楼层编号确定) 收件人(每个

  • 我有一个dynamodb表,用于存储在我的服务器上运行的进程的历史运行数据,我需要一个可以聚合这些进程并查看每个进程的最新数据的位置。每个进程都有自己的ProcessId,它是dynamodb表的分区键。排序键是开始时间 本质上,我需要为我提供的每个ProcessId检索最新的StartDateTime。我在aws sdk中使用nodejs lambda来检索数据。我已经研究过使用BatchGet

  • 我正在进行一个项目,我希望我的应用程序只能在一个系统上运行! 我所希望的是,当我将我的项目交付给一个特定的人时,他不能复制我的项目,可以在任何其他计算机系统上运行。我正在开发Java8 IDE(NetBeans)。 谢谢

  • 我试图在Android中创建一个应用程序,仅由1个广播接收器(而不是其他)组成。 广播接收器应该简单地捕捉广播(例如收到的短信,记录信息并完成)。然而,我注意到广播没有被接收器捕捉到,除非我指出我有主活动,如下Androidanifest.xml将显示: 我甚至不需要在应用程序中有一个活动类。此外,如果我在意图过滤器中删除android.intent.category.LAUNCHER或andro