DynamoDB 是无模式的吗?
是。DynamoDB 是无模式的。除了主键之外,你在建表时不定义任何属性或数据类型。每条 item 都可以带着自己那套独有的属性,而且它们可以逐条自由变化——所以你调整数据模型时不必跑模式迁移。
你要预先定义什么
只有主键:一个分区键(必需)和一个可选的排序键,外加它们的类型。其他一切都是任意的。你不需要声明列。
逐条变化的是什么
同一张表里的任意两条 item 可以拥有完全不同的属性。一条里可能装着 email 和 status;另一条可能装着 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 形状。
参考资料
- Core components of Amazon DynamoDB — Amazon DynamoDB Developer Guide
- What is Amazon DynamoDB? — Amazon DynamoDB Developer Guide
- Data modeling for DynamoDB tables — Amazon DynamoDB Developer Guide
最后核实于 2026-07-13,依据上方链接的 AWS 官方文档。
2026-07-28 针对 DynamoDB Local 3.3.0,用 Node v24.18.0 上的 @aws-sdk/client-dynamodb 3.1095.0 复现。两条 ValidationException 消息都是引擎原样输出。