所以,我正在使用带有node.js的AWS Lambda与DynamoDB进行交互,直到现在我都可以进行扫描,使用主键进行查询,等等。
但是,现在我需要进行查询或扫描,我不知道主键,我只有列的名称,我希望按该列过滤的参数和表名。
比如SQL语言:
SELECT * FROM user WHERE user_type = 'Moderator';
我在文档中搜索过,但我仍然无法做到这一点。有人能帮助我吗?
答案 0 :(得分:4)
DynamoDB是一个NoSQL数据库。 NoSQL数据库与传统的Relational(即SQL)数据库之间的区别在于,您可以获得更快的性能,但这会以牺牲运行复杂查询的灵活性为代价。如果您需要对数据运行复杂查询,则不应使用DynamoDB,因为它不适合您的要求。
在DynamoDB中,您只能对关键属性运行查询。否则,您必须运行扫描并返回整个表格,然后您可以对数据执行任何操作,例如过滤结果。
DynamoDB中的每个表通常至少有一个密钥,即主密钥,也称为哈希密钥或分区密钥。但是你也可以有一个Range Key,也称为Sort Key。在您的示例中,如果UserType是排序键,则在运行查询后,DynamoDB将返回UserType与“#Moderator”相等的所有分区中的所有行。
但您也可以在表上定义二级索引。辅助密钥可以是全局辅助密钥,也可以是本地辅助密钥。这为运行查询提供了更大的灵活性。有关更多详细信息,请参阅DynamoDB文档:
http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SecondaryIndexes.html
摘要:如果您无法控制DynamoDB表的设计,那么您可能只是在运行扫描时遇到困难。否则,请考虑重新设计表索引和键以满足您的要求。
答案 1 :(得分:3)
有两种方法可以执行此操作,具体取决于您的应用程序执行此查询的频率以及您对性能的关注程度,我会从最少的努力开始,但最不可扩展到大多数工作但最具可扩展性。
使用过滤器和投影表达式扫描表 - 因此,dynamo会根据分区键分割您的数据,除非已配置,否则不会保留任何索引。因此,在没有任何额外表配置的情况下获得所有主持人的综合列表的唯一方法是进行全表扫描,这会消耗大量IOPS,但如果这只是偶尔这样可能会很好。你可以添加一个"filter expression"让发电机返回给你的结果只有“user_type”='主持人',但在后端发电机仍在扫描整个数据库时,它会使进程更快一点传输结果较少,但它消耗相同的IOPS ..你可以更进一步使用“投影表达式”过滤只返回每行的“user_name”字段。 (如果您正在处理大项目,这可能会有所帮助。这也不会减少消耗的IOPS数量,但会减少返回给您的不必要的数据。虽然只有2个主持人,但这种方法不能很好地扩展。 ..数据库中的用户越多越慢。
添加全局二级索引这是中间立场,但它也需要花费成本,因为您需要为索引配置足够的IOPS才能跟上,但这里事情有点可控制。您可以使用不同的分区键来查看表的不同视图,但请注意,即使对于索引,您也需要a partition key that hashes以及基本上更远的表。 “user_type”不能很好地散列,所以你可以做的是有一个名为“moderator_name”的字段,它与“user_name”具有相同的值,但只存在于作为主持人的用户身上。接下来,您在此字段上创建二级索引,并且该索引中仅存在主持人。然后,您可以扫描此索引,以获取主持人列表,并且它不会消耗主表上的任何IOPS。这可能看起来有点hacky但是使用Dynamo它不像SQL,如果你构建一个好的表结构它可以处理任何查询,你需要专门构建你的Dynamo表来匹配你期望执行的读写类型..所以这导致了下一个选项
创建一个单独的“版主”表这是更多工作要开始,但如果您想要为您的网站添加版主特定功能,可能是更好的方法。如果您这样做,我建议您在主表中没有“user_type”,而只是查询此表,如果用户存在,则他们是主持人。这样做的原因是,如果没有SQL事务来组合写入,可能您的“user_type”字段和Moderator表将变得不一致。
使用Dynamo Streams将您的数据导出到SQL DB ,而Dynamo非常适合许多用例,而不是SQL DB,并牺牲了许多优秀且方便的SQL功能来提高性能和scalabiility ..再次让您的网站使用Dynamo获得速度可能是有意义的,但是然后创建有针对性的电子邮件广告系列在SQL数据库中具有相同的数据,因此您可以执行复杂的查询来创建针对特定用户子集的电子邮件广告系列。
在不同情况下,我使用了所有4种方法,需要强调的是“......取决于您的用例......”
答案 2 :(得分:2)
您可以使用user_type作为主键创建全局二级索引。然后从索引查询。