免费工具

DynamoDB 单表设计工具

输入你的实体以及你需要如何读取它们 —— 规划器会建议带实体前缀的 PK/SK 键模板、预览条目集合,并且仅在基础表无法服务某个模式时才添加 GSI。

实体
访问模式
建议的键模式
实体PKSK
UserUSER#<userId>USER#<userId>
Order
在 User 条目集合中
USER#<userId>ORDER#<orderDate>#<orderId>
GetItem · 基础表按 ID 获取 User
PK = USER#<userId> AND SK = USER#<userId>
Query · 基础表列出 User 下的 Order
PK = USER#<userId> AND begins_with(SK, 'ORDER#') ScanIndexForward: false
  • 排序键按字符串比较 —— 请以可排序的格式存储排序属性(ISO-8601 日期、零填充的数字)。
Query · GSI1按 email 查找 User
GSI1PK = USER#EMAIL#<email>
  • GSI 不强制唯一性 —— 请在写入时用基础条目上的条件表达式来防止重复。
全局二级索引
GSI1为 User 条目建立索引
GSI1PK = USER#EMAIL#<email> GSI1SK = USER#EMAIL#<email>
  • GSI 不强制唯一性 —— 请在写入时用基础条目上的条件表达式来防止重复。
示例条目
实体PKSKGSI1属性
UserUSER#user-1USER#user-1USER#EMAIL#user-1@example.com USER#EMAIL#user-1@example.comuserId: user-1, email: user-1@example.com
OrderUSER#user-1ORDER#2025-06-01#order-1orderId: order-1, orderDate: 2025-06-01, userId: user-1
OrderUSER#user-1ORDER#2025-06-02#order-2orderId: order-2, orderDate: 2025-06-02, userId: user-1
表定义(CreateTable JSON)
{
  "TableName": "AppTable",
  "BillingMode": "PAY_PER_REQUEST",
  "AttributeDefinitions": [
    {
      "AttributeName": "PK",
      "AttributeType": "S"
    },
    {
      "AttributeName": "SK",
      "AttributeType": "S"
    },
    {
      "AttributeName": "GSI1PK",
      "AttributeType": "S"
    },
    {
      "AttributeName": "GSI1SK",
      "AttributeType": "S"
    }
  ],
  "KeySchema": [
    {
      "AttributeName": "PK",
      "KeyType": "HASH"
    },
    {
      "AttributeName": "SK",
      "KeyType": "RANGE"
    }
  ],
  "GlobalSecondaryIndexes": [
    {
      "IndexName": "GSI1",
      "KeySchema": [
        {
          "AttributeName": "GSI1PK",
          "KeyType": "HASH"
        },
        {
          "AttributeName": "GSI1SK",
          "KeyType": "RANGE"
        }
      ],
      "Projection": {
        "ProjectionType": "ALL"
      }
    }
  ]
}

用于 aws dynamodb create-table --cli-input-json 的普通 JSON —— 通用字符串类型的 PK/SK 属性、GSI 投影为 ALL、按需计费。

成本提示
每个条目的读取单元(最终一致)
0.5 RCU
每个条目的写入单元
1 WCU
每月按需估算(us-east-1)—— 仅基础表
US$4.93
包含 GSI 写入复制(×1)
US$8.21

每个 GSI 都存储它对每个条目的一份投影副本,因此一次表写入也会在每个 GSI 上消耗写入容量。该估算假设完整投影,并采用与我们的定价和项大小计算器相同的 4 KB 读取 / 1 KB 写入取整方式。

从访问模式到键模式

单表设计从读取出发,而非从实体出发:你不再规范化多张表并在查询时做联接,而是列出应用需要获取数据的每一种方式 —— 按 ID 获取用户、按最新在前列出某用户的订单、按 email 查找账户 —— 并塑造键,使每一种方式都是一次 GetItem 或 Query。基础表无法满足的每一个模式都要以一个索引为代价,而这笔权衡应当在你创建表之前就清晰可见。

这个规划器让这笔权衡显式化。它确定性地应用标准的单表规则 —— 带实体前缀的复合键、用于一对多模式的条目集合、其余情形则用倒排或属性范围的 GSI —— 而当某个模式无法干净地被服务时,它会如实说明,而不是假装可以。示例条目表展示了最终的行在一个分区内实际是如何彼此相邻排列的。

输出是一份普通的 CreateTable JSON 文档,带有通用的字符串类型键属性 —— 没有任何工具专属的东西需要日后拆解 —— 外加复用了我们定价和项大小计算器所用的、精确的 4 KB 读取 / 1 KB 写入取整方式的成本提示。

还不熟悉这些概念,或者不确定这种方法是否适合你的工作负载? 我们的单表设计指南 从第一性原理讲解这一理念,而 何时不应使用它 则坦诚地介绍其反面情形。模式确定后, 在 DynamoDB 查询构建器中组装真正的请求 ,或用以下工具估算完整的每月账单: DynamoDB 定价计算器.

常见问题

什么是 DynamoDB 中的单表设计?

一种建模方法:应用的所有实体类型共享一张表,并使用通用的分区键和排序键属性(PK/SK)。相关的条目共享同一个分区键,因此一次 Query 就能把它们一起取出 —— 该设计由你的访问模式驱动,而非由规范化的实体结构驱动。

这个规划器如何决定键设计?

依据固定、公开的规则 —— 确定性的,而非生成式的。每个实体一开始都是它自己条目集合的根,使用带实体前缀的键;第一个列出子项的模式会把子项通过复合排序键移入其父项所在的分区;按其他属性查找、第二个父项以及列出全部的模式会成为 GSI 建议;而规则无法干净服务的模式会被标记为不支持,而不是硬造一个设计。

访问模式何时需要全局二级索引?

当基础表的键布局无法满足它时:按子项自身的 ID 获取一个已改归属的子项、在第二个父项下列出相同的条目、按诸如 email 这样的非键属性查找条目,或列出某一类型的全部条目。这些都需要对同一份数据重新设定键,而这只有索引才能做到 —— 规划器会为每种键形状建议一个索引,并在共享该形状的多个模式之间复用它。

GSI 如何影响 DynamoDB 成本?

每个 GSI 都维护它所覆盖条目的一份投影副本,因此每次表写入还会在每个投影该条目的 GSI 上消耗写入容量,而存储则按每份副本计费。成本卡片会显示一个基础表估算,以及一个计入 GSI 写入复制的估算,采用与我们的定价和项大小计算器相同的 4 KB 读取 / 1 KB 写入取整方式。

规划器会把我的数据模型上传到任何地方吗?

不会。该页面是静态的,设计完全在你的浏览器中计算 —— 实体名称、ID 属性和访问模式永远不会到达服务器。设计离开页面的唯一方式是“复制链接”的 URL,它会把设计打包进链接,因此分享始终是一个有意为之的动作。

无需控制台即可使用 DynamoDB

DynoTable 是面向 DynamoDB 的快速桌面客户端 —— 浏览表、运行 SQL 风格的查询,并在本地编辑项。