我在设计DynamoDB表以支持相当简单的访问模式时遇到问题。希望您能对我有所帮助:)

我有4种不同的产品类型(A,B,C和D),它们具有价格位置(国家/州/市)。

访问模式为:

  • 按产品筛选类型
  • 按产品筛选类型位置
  • 按产品筛选类型位置价格
  • 按产品类型位置价格过滤,并按价格
  • 排序

    问题是位于USA#NY#NY的产品也必须在USA#NY和USA中可用。而且,用户需要首先能够按价格过滤并按价格/便宜价分类。

    示例:

    数据:

    产品:ID_1 |类型A |位置美国#NY#NY |价钱100 $
    产品:ID_2 |类型A |位置美国#NY#NY |价钱200 $

    用例:
  • 用户U1在USA#NY#NY中搜索价格昂贵的第一个
  • 用户U2搜索价格为<
    250美元在美国#NY便宜的第一张

  • 预期结果:
  • U1应该获得ID_2,ID_1
  • U2应该获得ID_1,ID_2

  • 两种产品都应按正确的顺序显示给两个用户,即使他们在不同的区域进行搜索。

    为了能够按位置价格进行过滤,并按价格进行排序,我想出了这个解决方案,但是,很多数据被复制了,我相信必须有一个更好的解决方案:

    PK | SK&GSI PK | GSI SK |其他产品详细信息(重复数据)
    -------------------------------------------------- -------------------------
    ID | TYPE |价格|图片,名称等
    ID | TYPE#USA |价格|图片,名称等
    ID | TYPE#USA#NY |价格|图片,名称等
    ID | TYPE#USA#NY#NY |价格|图片,名称等

    这解决了每种访问方式:
  • 按产品筛选类型

    GSI PK = TYPE
  • 按产品筛选类型位置

    GSI PK = starts_with(TYPE#USA#NY#...)
  • 按产品筛选类型位置价格

    GSI PK = TYPE#USA&GSI SK> 150

    GSI PK = TYPE#USA#NY&GSI SK> 150
  • 按产品类型位置价格过滤,并按价格排序

    GSI PK = TYPE#USA&GSI SK> 150 ScanIndexForward是/否

    GSI PK = TYPE#USA#NY&GSI SK> 150 ScanIndexForward真/假

  • 读取是有效的,但是很多数据会重复(价格和产品详细信息),并且更新项目需要多次写入。

    是否可以在不重复所有产品详细信息的情况下实现这一目标?

    最佳答案

    我认为您误解了分层模式

    你只需要

    PK = ID

    GSI
    PK =类型
    SK = COUNTRY#STATE#CITY

    然后,您可以查询GSI

  • 查询(GSI,PK ='TYPEA')
  • 查询(GSI,PK ='TYPEA',SK以'USA#'开头)
  • 查询(GSI,PK ='TYPEA',SK以'USA#NY#'开头)
  • 查询(GSI,PK ='TYPEA',SK以'USA#NY#NY#'开头)

  • 可以将价格过滤添加到上述任何查询中。
    查询(GSI,PK ='TYPEA',SK以'USA#NY#NY#'开头,过滤价格> 100.00)

    请注意,以这种方式过滤不会节省任何读取容量,仅过滤客户端可能会更有效。

    关键是您只需要(并且被允许)表中每行GSI 1行

    唯一的问题是,您希望任何一种类型的数据超过10GB吗?像DDB表一样,GSI的每个分区限制为10GB。如果您确实希望每种类型超过10GB,那么我会重新考虑这种类型是有效的访问模式的想法。没有人会滚动浏览10GB的数据。

    老实说,我不喜欢DDB表,这些表不能处理至少一种预期的访问模式。如果type对驱动程序有很大的影响,我将考虑使用如下表:

    PK =类型
    SK = ID

    LSI
    PK =(与表相同)
    SK = COUNTRY#STATE#CITY

    现在您的查询成为
  • 查询(表格,PK ='TYPEA')
  • 查询(LSI,PK ='TYPEA',SK以'USA#'开头)
  • 查询(LSI,PK ='TYPEA',SK以'USA#NY#'开头)
  • 查询(LSI,PK ='TYPEA',SK以'USA#NY#NY#'开头)

  • 而且您不必为GSI支付额外费用。

    编辑
    在考虑价格过滤器时,它是否真的会在性能或成本上产生很大的差异。您为每1MB RCU数据付费,而不管返回的数据是1行还是100行。那么,您的行数有多大,您希望过滤的价差有多大?

    除了发电机以外,您是否考虑过其他选择? Aurora RDS当然可以提供您似乎非常需要的查询灵活性。也许除了DDB之外还添加Elasticsearch。

    关于amazon-web-services - DynamoDB分层数据和条件表设计,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57304783/

    10-11 06:48