Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Amazon web services notes应用程序的DynamoDB分区键选择_Amazon Web Services_Nosql_Amazon Dynamodb - Fatal编程技术网

Amazon web services notes应用程序的DynamoDB分区键选择

Amazon web services notes应用程序的DynamoDB分区键选择,amazon-web-services,nosql,amazon-dynamodb,Amazon Web Services,Nosql,Amazon Dynamodb,我想创建一个DynamoDB表,它允许我保存用户的注释 我拥有的属性: 用户id 注释\u id(uuid) 类型 正文 我需要的主要问题包括: 获取某个用户的所有注释 得到一张特别的纸条 获取特定类型的所有注释(较少使用的查询) 我知道在性能和DynamoDB分区方面,note_id将是正确的选择,因为它们是唯一的,并且将平均分布在分区上,但另一方面,在不扫描所有项目或使用GSI的情况下获取用户的所有注释要困难得多。如果它们是唯一的,我认为使用排序键没有任何意义 另一种选择是使用use

我想创建一个DynamoDB表,它允许我保存用户的注释

我拥有的属性:

  • 用户id
  • 注释\u id(uuid)
  • 类型
  • 正文
我需要的主要问题包括:

  • 获取某个用户的所有注释
  • 得到一张特别的纸条
  • 获取特定类型的所有注释(较少使用的查询)
我知道在性能和DynamoDB分区方面,note_id将是正确的选择,因为它们是唯一的,并且将平均分布在分区上,但另一方面,在不扫描所有项目或使用GSI的情况下获取用户的所有注释要困难得多。如果它们是唯一的,我认为使用排序键没有任何意义

另一种选择是使用user\u id作为分区键,note\u id作为排序键,但是如果我有某些用户的note数量比其他用户大得多,这不会影响我的性能吗

使用一个唯一的分区键(比如note_id)来与DynamoDB分区进行良好的伸缩,并使用GSIs来创建我的查询,还是使用一个分区键作为我的主查询(user_id)更好


谢谢

我把这看作两张表。notes表上带有GSI的用户和notes。不知道你还能怎么做。使用userId作为主键,note_id作为排序键要求您只能在同时知道user_id和note_id的情况下检索元素。使用DynamoDB,如果不扫描,则必须满足主键中的所有元素,因此分区和排序(如果有)都必须满足。下面是我将如何做到这一点

获取某个用户的所有笔记

当用户创建注释时,我会将其添加到users notes属性的users表中。当您想要获取所有用户注释时,请检索该用户并访问存储在其中的注释ID数组/列表

{ userId: xxx,
  notes: [ note_id_1,note_id_2,note_id_3]
}
获取特定的注释

使用node_id作为主键的notes表将使这变得容易

{
noteId: XXXX,
note: "sfsfsfsfsfsf",
type: "standard_note"
}
获取特定类型的所有笔记(使用较少的查询) 我会在notes表上使用一个GSI,将属性“note_type”和note_id投射到它上面

更新


你可以用一张桌子和一个GSI来完成这件事(如何实现请参见下面的两个答案),但我不会这么做。您的数据模型如此简单,为什么要比用户和注释更复杂呢

最简单、最具成本效益的方法可能是单一表格:

表格结构

  • 注意\u id(uuid)/散列键
  • 用户id
  • 类型
  • 正文
有两个GSI,一个用于“获取某个用户的所有注释”,另一个用于“获取某个类型的所有注释(较少使用的查询)”:

GSI用于“获取某个用户的所有笔记”

  • 用户id/哈希键
  • 注\u id(uuid)/范围键
  • 类型
  • 正文
关于这一点,您的查询中哪一个最频繁:“获取某个用户的所有注释”或“获取特定注释”?如果是前者,那么您可以将GSI键交换为表键,反之亦然(如果这有意义的话——本质上,将
用户id
+
注释id
作为表键,将
注释id
作为GSI键)。这也取决于你如何构建你的
用户id
——我怀疑你已经了解了;确保您的
用户\u id
不是连续的-将其设置为UUID或类似的

GSI用于“获取特定类型的所有注释(较少使用的查询)”

  • 类型/哈希键
  • 注\u id(uuid)/范围键
  • 用户id
  • 正文

根据
type
字段的基数,您需要测试GSI在这里是否真的有用

如果GSI没有什么好处,并且您需要更高的性能,那么另一种选择是将
类型
note_id
数组一起存储在一个单独的表中。注意这张便笺的400k物品限制,以及您需要执行另一个查询以获取便笺的
文本


使用此表结构和GSIs,您可以对所查找的信息进行一次查询,而不是在有两个表的情况下进行两次查询


当然,您最了解自己的数据——最好从您认为最好的数据开始,然后对其进行测试,以确保它满足您的需求。DynamoDB的价格是由供应的吞吐量+存储的索引数据量来确定的,因此创建具有多个属性的“fat”索引项目,如上所述,如果有大量数据,那么执行两次查询并存储较少的索引数据可能会更具成本效益。

我将使用用户id作为主要分区(哈希)键,并将_id作为主要范围(排序)键

您已经注意到,在理想情况下,每个分区键都以相同的规律性访问,以优化性能,请参阅。只要你有一大批定期登录的用户,使用user_id就完全可以了。事实上,AWS特别鼓励此选项(请参阅上面链接中的“选择分区键”表)

这种方法还将使应用程序代码比其他方法简单得多

然后,您还有第二个选择,即是否为get notes by type查询应用全局二级索引。与主键不同,GSI键不需要是唯一的(请参阅,因此我建议您只使用type作为GSI分区键,而不使用范围键)

使用GSI的明显优点是,当您执行注释类型查询时,结果更快。但是,您也应该意识到缺点。GSI比您的表有单独的吞吐量余量,因此您需要在表吞吐量的基础上提供这一点(额外成本).如果您没有为GSI提供足够的读取单位,它可能会以较慢的速度结束