本文介绍了如何设计关键模式以使每个应用程序只有一个 DynamoDB 表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

According to DynamoDB doc: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-general-nosql-design.html

您应该在 DynamoDB 应用程序中维护尽可能少的表.大多数设计良好的应用程序只需要一张表."

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

But according to my experience you always have to do the opposite thing due to partition key design.

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

Let's consider the next situation. We have several user roles, for example, "admin", "manager", "worker". Usual workflow of an admin is to CRUD manager data, where read operation is to get not one manager but all manager list. The same is for the manager - he CRUDs worker data.We have only two scenarios of key usage for both cases:

  • 获取所有项目的列表(项目键无关紧要)
  • 使用其完整密钥处理特定项目.

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

Naturally we should have uniformly distributed partition key (as the doc emphasises) so we can't select user role for it and should use user id. Since we already have as partition key some random id, we don't need sort key at all since it simply doesn't work - we already access exectly one user by only using the partition key part. At this point we realize that user id is working like a charm for CUD operations but for every R operation we need to scan all the table and then filter the result by user role which is ineffective. How can this be improved? Very naturally - let's just have own table for each user type! Then we will scan for manager list from admin API and for worker list from the manager one.

我使用 DynamoDB 快一年了,仍然无法使用.对我来说,现实情况是,对于现实生活场景,排序键是你永远无法使用的(我唯一真实的情况是同时访问属于不同类型的两个用户的协议"之类的项目,所以主键是 { partion: "managerId", sort: "userId" } 二级全局索引是 { partition: "userId", sort: "managerId" } 所以我可以有效地查询所有特定的经理协议列表或所有特定的用户协议列表仅提供查询的相应经理或用户 ID.该方法在此处的文档中进行了讨论:https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-adjacency-graphs.html).

I use DynamoDB almost for a year and still can't get it. For me the reality is that for real life scenarios sort key is something that you can never use (the only real case for it I had was to access items like "agreements" that belong to the two users of different types the same time, so the primary key was { partion: "managerId", sort: "userId" } and secondary global index was { partition: "userId", sort: "managerId" } so I could effectively query for all particualar manager agreement list or all particular user agreement list providing only corresponding manger or user id for the query. The approach is discussed in doc here: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-adjacency-graphs.html).

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

I feel that I don't understand the concept at all. What can be an effective way of key schema for provided example to use only one DynamoDB table for both user types?

推荐答案

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

It sounds like what you need in this case is a Global Secondary Index (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html) where the partition key is the user role. That way, you can query all users with a particular role through that UserRoleIndex and, with the help of a sort key on the user ID, single out one particular user within that role.

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

Alternatively, if you are starting from scratch with a new table, you might not even need an index (unless you don't know the role of a user when you delete them). You can use a "composite primary key" (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.PrimaryKey) where the partition key and the sort key would be the same as in the index I am suggesting above.

使用您在问题中使用的相同表示法,我会推荐 { partition: "userRole", sort: "userId" }.

Using the same notation that you used in your question, I would recommend { partition: "userRole", sort: "userId" }.

DynamoDB 有时可能难以理解,而且在某些情况下,传统 SQL 数据库确实更有意义.来自 AWS re:Invent 2018 的这段视频很好地了解了两者之间的区别:https://www.youtube.com/watch?v=HaEPXoXVf2k&feature=youtu.be.

DynamoDB can be hard to understand sometimes and there definitively are cases where a traditional SQL database makes more sense. This video from AWS re:Invent 2018 is great to understand the difference between the two: https://www.youtube.com/watch?v=HaEPXoXVf2k&feature=youtu.be.

不过,在您的情况下,您似乎有一个非常清晰的访问模式,因此 DDB 会为您工作.

In your case, though, it looks like you have a very clear access pattern, so DDB would work for you.

这篇关于如何设计关键模式以使每个应用程序只有一个 DynamoDB 表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 09:16