Amazon dynamodb 项目投票-如何设计数据库/aws lambda以最小化aws成本

Amazon dynamodb 项目投票-如何设计数据库/aws lambda以最小化aws成本,amazon-dynamodb,aws-lambda,Amazon Dynamodb,Aws Lambda,我在一个网站上工作,该网站主要显示注册用户创建的项目。所以我认为95%的API调用是读取单个项,5%是存储单个项。系统采用AWS API网关设计,该网关调用AWS Lambda函数,该函数处理DynamoDB中的数据 我的下一步是实施投票系统(向上投票/向下投票),包括基本的投票规则: 每个注册用户只能对每个项目投票一次,以后只允许更改该投票 投票数需要显示给每个项目旁边的所有用户 项目只有单个项目视图,并且(几乎)从未在列表视图中显示 我需要的唯一列表视图是“投票前100项”,但每天计算一次

我在一个网站上工作,该网站主要显示注册用户创建的项目。所以我认为95%的API调用是读取单个项,5%是存储单个项。系统采用AWS API网关设计,该网关调用AWS Lambda函数,该函数处理DynamoDB中的数据

我的下一步是实施投票系统(向上投票/向下投票),包括基本的投票规则:

  • 每个注册用户只能对每个项目投票一次,以后只允许更改该投票
  • 投票数需要显示给每个项目旁边的所有用户
  • 项目只有单个项目视图,并且(几乎)从未在列表视图中显示
  • 我需要的唯一列表视图是“投票前100项”,但每天计算一次并提供缓存版本是可以的
我的目标是设计一个数据库/lambda,以最小化AWS的成本。使逻辑工作起来很容易,但我不确定我的解决方案是否是最优的:

  • 我的
    items
    表当前有hashkey
    slug
    和sortkey
    version
  • 我用hashkey
    slug
    和sortkey
    user
    创建了
    items投票
    表,还创建了
    投票
    字段(包含-1或1)
  • 我将字段
    投票
    添加到
    项目
    表中
  • API调用upvote/downvote将插入到
    项目投票
    表中,但在检查用户尚未以这种方式投票的约束之前。然后,在第二个查询中,使用更新的投票计数更新
    表。(1个API调用和2个db查询)
  • 用于显示项目的旧API调用保持不变,但也会获取新的
    投票
    计数(1个API调用和1个db查询)
我想知道,如果避免新的
项目投票
表,并将用户投票存储在
项目
表中,是否可以做得更好?这样看来可以保存一个查询,并且可以节省一半的lambda执行时间,但我担心这可能会使该表太大/太复杂。每个
用户
字段都是一个10个字符的用户ID,因此如果项目获得数千票,我不确定与原始解决方案相比,Lambda/DynamoDB的表现如何


我不希望很快会有数千人投票,但这并非不可能发生在少数项目上,我希望避免在不久的将来需要迁移到不同的解决方案。

我建议使用SET DynamoDB(即SS)属性来维护投票反对该项目的用户列表。如下所示:-

  • 向上投票:['user1','user2']
  • 否决票:['user1','user2']
使用UpdateExpression更新投票时,可以使用ADD操作符,该操作符仅在不存在时添加要设置的用户

添加-如果属性不存在,则将指定的值添加到项中 已经存在。如果属性确实存在,则ADD的行为 取决于属性的数据类型:

如果现有数据类型为集合,而值也是集合,则 值将添加到现有集。例如,如果属性 值是集合[1,2],指定的添加操作[3],然后是 最终属性值为[1,2,3]。如果执行添加操作,则会发生错误 为集合属性指定,而指定的属性类型不指定 与现有集类型不匹配。两组必须具有相同的属性 基本数据类型。例如,如果现有数据类型是集合 对于字符串,该值还必须是一组字符串

这样,您就不需要检查用户是否已经对该项目进行了向上投票或向下投票


您可能需要确保的唯一一件事是,相同的用户不应该出现在upvote和downvote集合中。或许,您可以使用删除或ConditionExpression来实现此目的。

谢谢,这消除了我的一部分疑问,即如何处理登记投票。但第二部分仍然存在:以这种方式登记数千张选票的限制在哪里?是否存在任何性能问题?每个用户ID有1000个投票权x 10个字符,大约有1KB的数据。我认为DynamoDB的限制是每记录400K。若我为项目数据预留100KB,那个么投票的空间就剩下300KB,这意味着投票的限制大约为300000票。这远远超出了我的需要,但查询性能又如何呢?另外,为了显示投票数,我在想,我应该在每次收到一个项目(95%的请求)时只对集合中的项目进行计数,还是可以(在更新投票的同一过程中)计算总计并将其存储为项目的属性?Ans1:它不应影响性能,因为您拥有查询项目所需的哈希键(这是最有效的查询方式)。只要项目大小不超过4KB,就不会产生任何问题。回答2:我会在客户方点票。JavaScript具有计算数组中值的数量的函数。不需要维护单独的计数属性,也不需要创建额外的开销来维护它。您说过“只要项目大小不超过4KB,就不会产生任何问题。”。。。你是说400KB?我不知道这4K是从哪里来的。至于在客户端计算投票,这意味着将所有用户名从DB和API拉到客户端。它将在很长一段时间内工作,但对于一般讨论,如果大多数流行项目获得数千票,简化DynamoDB查询的好处是否会随着带宽的增加而丢失(10K的数据仅用于使array.count依赖于客户端)?是的,我的意思是400kb。我知道你的分数了。在这种情况下,可以单独维护count属性。