DynamoDB 是无模式的吗?

是。DynamoDB 是无模式的。除了主键之外,你在建表时不定义任何属性或数据类型。每条 item 都可以带着自己那套独有的属性,而且它们可以逐条自由变化——所以你调整数据模型时不必跑模式迁移。

你要预先定义什么

只有主键:一个分区键(必需)和一个可选的排序键,外加它们的类型。其他一切都是任意的。你不需要声明列。

逐条变化的是什么

同一张表里的任意两条 item 可以拥有完全不同的属性。一条里可能装着 emailstatus;另一条可能装着 orderTotal 和一个嵌套的 address 映射。你写什么,DynamoDB 就存什么。

无模式止步于何处

无模式有一条精确的边界。主键在每次写入时都会被校验;其他什么都不会。两条毫无共同属性的 item 可以毫无怨言地进同一张表:

await client.send(
  new PutItemCommand({
    TableName: 'people',
    Item: {pk: {S: 'USER#1'}, email: {S: 'a@b.c'}, status: {S: 'active'}}
  })
);
await client.send(
  new PutItemCommand({
    TableName: 'people',
    Item: {
      pk: {S: 'ORDER#1'},
      orderTotal: {N: '42.5'},
      address: {M: {city: {S: 'Madrid'}}},
      tags: {SS: ['a', 'b']}
    }
  })
);

两次都成功。现在把同一个分区键写成数字而不是字符串:

ValidationException: One or more parameter values were invalid: Type mismatch for key
HTTP 400

再完全省略 pk

ValidationException: One of the required keys was not given a value
HTTP 400

这两次拒绝就是全部的模式。键属性必须存在,而且必须与 AttributeDefinitions 里声明的类型一致。除此之外的一切都会被照单接收。

打字错误也照样通过。写入时不会有任何东西告诉你 staus 本该是 status

它为什么有用

  • 无需迁移——随时增删属性。
  • 混合实体——多种实体类型可以共用一张表(单表设计)。
  • 可演进——模型随需求一起变。

任何你所依赖的形状,都由你的应用而不是数据库来保证。

无模式不会放宽什么

无模式只作用于非键属性。DynamoDB 的其他每一条限制仍然成立:

  • 每条 item 400 KB——属性名和值都计入上限。
  • 值内部的 map 与 list 最多 32 层嵌套
  • 单个属性名最长 65,535 字节
  • 每次 BatchWriteItem 调用最多 25 条 item

你可以在一条上放 status 字符串、在下一条省略它,但不能在任何一条里存 500 KB 的 blob。写入前用 item size calculator 量一下 payload,在一张表里混实体类型时读 单表设计

在 DynoTable 中: 在任意表上打开 设置 并为其建立索引。推断出的 schema 来自采样 item,并且标注得很老实——它显示你写过的内容,而不是你声明过的内容。本地索引如何采样和刷新见 表概览与索引

深入了解

参见单表设计和用于混合 item 的 type 属性模式。下载 DynoTable 来并排查看真实的 item 形状。

参考资料

最后核实于 2026-07-13,依据上方链接的 AWS 官方文档。

2026-07-28 针对 DynamoDB Local 3.3.0,用 Node v24.18.0 上的 @aws-sdk/client-dynamodb 3.1095.0 复现。两条 ValidationException 消息都是引擎原样输出。

无需控制台即可使用 DynamoDB

一款快速的 DynamoDB 桌面客户端,可运行 DynamoDB 无法执行的真正 SQL——JOINs、GROUP BY、聚合——并支持可视化编辑和运行在你自己的 Bedrock 密钥上的 AI agent。

30 天免费试用,无需信用卡 — 之后为无时间限制的免费版。