【问题标题】:Single table DynamoDB design tips单表 DynamoDB 设计技巧
【发布时间】:2021-09-26 07:15:05
【问题描述】:

我有一个旧应用程序,我正在对其进行现代化改造并引入 AWS。我将使用 DynamoDB 作为数据库,并希望采用单表设计。这是一个多租户应用程序。

应用程序将包括组织、网点、客户和交易。 一切都源于一个组织,一个组织可以有多个网点,网点可以有多个客户,客户可以有多个交易。

访问模式预计如下:

  • 按 ID 获取客户
  • 按姓名或电子邮件搜索客户
  • 获取指定网点的所有客户
  • 获取客户的所有交易
  • 获取网点的所有交易
  • 获取指定时间段内某个网点的所有交易(时间戳将随每笔交易一起存储)
  • 获取给定组织的所有网点
  • 通过 ID 获取插座

我一直在阅读单表设计并利用主键和排序键来启用这种访问,但现在我无法完全弄清楚表/模式设计。 客户将附上 outletID 和 OrganiastionID,所以我应该始终知道这些 ID

数据结构(可修改)

组织:

  • 身份证
  • 姓名
  • 所有者
  • 奥特莱斯列表
  • createdAt(时间戳)

分店:

  • 组织 ID
  • 分店名称
  • 客户数量
  • 交易数量
  • createdAt(时间戳)

客户:

  • 身份证
  • 组织 ID
  • 出口 ID
  • 名字
  • 姓氏
  • 电子邮件
  • 总交易量
  • 总花费
  • createdAt(时间戳)

交易:

  • 身份证
  • 客户 ID
  • 组织 ID
  • 出口 ID
  • createdAt(时间戳)
  • 类型
  • 价值

【问题讨论】:

  • 在我看来,您的所有数据和数据访问模式至少需要 2 或 3 个表。为什么您觉得有必要将所有内容都限制在一个表中?

标签: amazon-dynamodb


【解决方案1】:

彻底了解您的实体和访问模式,您将有了一个良好的开端!我已经尝试为这些访问模式建模,但请记住,这不是建模解决方案的唯一方法。 DynamoDB 中的数据建模是迭代的,因此非常这种特定设计可能无法 100% 适合您的用例。

先免责声明,让我们开始吧!

我使用名为 data 的单个表和名为 GSI1 和 GSI2 的全局二级索引 (GSI) 对您的访问模式进行了建模。每个 GSI 都有分区键和排序键,分别命名为 GSI#PK 和 GSI#SK。

基表模拟以下访问模式:

  • 通过ID获取客户:getItem where PK=CUST#<id> and SK = A
  • 获取客户的所有交易:query where PK=CUST#<id> and SK begins_with TX
  • 通过 ID 获取插座:getItem where PK=ORG#<id> and SK = A
  • 获取所有客户的网点:query where PK=OUT#<id>#CUST

最后一个访问模式可能需要更多解释。我选择使用独特的 PK/SK 模式来模拟商店和客户之间的关系,其中 PK 是OUT#<id>#CUST,SK 是CUST#<id>。当您的应用程序为特定客户记录交易时,它可以使用批量写入操作在 DDB 中插入 两条 记录。批量写入操作会执行两个操作:

  • 将新事务写入客户分区(例如 PK = CUST#1 和 SK = TX#<id>
  • 将新记录写入 CUSTOMERLIST 分区(例如 PK = OUT#<id>#CUST 和 SK = CUST#<id>)。如果这条记录已经存在,DynamoDB 只会覆盖现有记录,这对您的用例来说很好。

转到 GSI1:

GSI1 支持以下操作:

  • 按组织获取网点:query GSI1 where GSI1PK = ORG#<id>
  • 按出口获取交易:query GSI1 where GSI1PK = OUT#<id>
  • 在给定时间段内按出口获取交易:`query GSI1 where GSI1PK=OUT# and GSI1SK between and

最后,还有 GSI2

GSI2 支持以下事务:

  • 按组织获取交易:query GSI2 where GSI2PK = ORG#<id>
  • 按组织获取给定时间段内的交易:query GSI2 where GSI2PK=OUT#<id> and GSI2SK between <period1> and <period2>

对于您的最终访问模式,您已要求支持通过电子邮件或姓名搜索客户。 DynamoDB真的擅长通过主键查找项目。 DynamoDB 不适合搜索,其中需要模糊或部分匹配。如果您需要完全匹配电子邮件或姓名,您可以在 DynamoDB 中通过将电子邮件//姓名合并到用户项的主键中来实现。

我希望这能给您一些关于如何为您的访问模式建模的想法!

【讨论】:

  • 抱歉回复晚了,这个答案太棒了,正是我所追求的。谢谢!
  • 我很高兴这有帮助!如果它解决了您的疑虑,请考虑接受我的回答。
猜你喜欢
  • 2011-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-31
  • 1970-01-01
  • 1970-01-01
  • 2017-05-13
相关资源
最近更新 更多