DynamoDB 能存储 JSON 吗?
能。DynamoDB 通过把 JSON 映射到它的文档类型来存储 JSON:map(M)对应对象,list(L)对应数组,最多嵌套 32 层。每个项最多 400 KB。DynamoDB 的类型系统是 JSON 的超集,所以任何 JSON 文档都能作为一个项存起来,然后被过滤、更新和读取。
JSON 是怎么映射到 DynamoDB 类型的
- JSON 对象 → Map (M)
- JSON 数组 → List (L)
- 字符串 / 数字 / 布尔值 / null → S / N / BOOL / NULL
列表和映射最多能嵌套 32 层,所以一整份 JSON 文档就是一个项。
存下来的大小比 JSON 更小
那种带类型标签的传输格式看着很浪费,于是人们以为自己是按它计费的。并不是。DynamoDB 是按项大小收费的,而项大小是每个属性名加上每个值的总和,不含 JSON 的引号、冒号、逗号和花括号。
一份九个属性的订单文档,带一个嵌套地址、一个两行的商品数组和一个两元素的标签列表,用三种方式量出来是:
| 测量方式 | 字节 |
|---|---|
| 过网发送的 DynamoDB JSON | 607 |
| 同一份文档作为压缩的普通 JSON | 447 |
| 计费的项大小 | 350 |
所以存下来的项比你一开始那份 JSON 小 22%,比运载它的那个请求小 42%。数字承担了大部分功劳:149.97 存下来大约 4 字节,而文本形式是 6 个字符。字符串和名字是精确计数的;AWS 记载的数字编码大致是每两位有效数字一个字节,所以把 350 理解成精确到几个字节,而不是精确到一个字节。
真正让你花钱的是取名。属性名和映射键占了那 350 字节中的 148 字节,即整个项的 42%,而且每一份副本你都要为它们付费。把 shippingAddress 缩短成 addr,在十亿个项上就是一笔实打实的节省。你可以在项大小计算器里给任何文档量大小,我们已经拿引擎自己的计费边界校验过它:它算作 1,024 字节的项消耗一个写单元,1,025 字节则消耗两个。
JSON 在一次往返中丢了什么
DynamoDB 把数字存成 38 位精度的十进制数,所以一个 JSON 数字是被规范化了,而不是被原样保留。写进去再直接读回来:
{"price": 19.90} -> {"price": {"N": "19.9"}}
{"qty": 1.0} -> {"qty": {"N": "1"}}
{"limit": 1e5} -> {"limit": {"N": "100000"}}
{"id": 9007199254740993} -> {"id": {"N": "9007199254740993"}}最后那一行才是有用的。DynamoDB 精确地保住了这个整数,而在 Node 里 JSON.parse('{"id":9007199254740993}') 给你的是 9007199254740992。如果 ID 很重要,就把它们存成字符串。
有两类 JSON 文档 DynamoDB 根本不收:空的键({"": "x"} 会抛 ValidationException: Empty attribute name,嵌套映射里也一样),以及超出精度上限的数字,它会抛 ValidationException: DynamoDB only supports precision up to 38 digits。
唯一的告诫
DynamoDB 的类型是 JSON 类型的超集。Binary(B)和 Set(SS/NS/BS)属性在 JSON 里没有直接对应物,所以当你转回普通 JSON 时,集合会序列化成数组,二进制会变成 base64。
怎么使用它
你可以直接对嵌套的 JSON 属性做操作——在某个映射字段上过滤、更新列表里的某一个元素——而不必重写整个项。
深入了解
见 DynamoDB JSON 与编组,并用 JSON 转换器在普通 JSON 和 DynamoDB JSON 之间转换。下载 DynoTable 来可视化地编辑 JSON 项。
参考资料
- Supported data types and naming rules in Amazon DynamoDB — Amazon DynamoDB Developer Guide
- Quotas in Amazon DynamoDB — Amazon DynamoDB Developer Guide
- DynamoDB Update – JSON, Expanded Free Tier, Flexible Scaling, Larger Items — AWS News Blog
最后核实于 2026-07-13,依据上方链接的 AWS 官方文档。
2026-07-28 测量并复现。三个字节数分别来自我们自己的项大小计算器和序列化后的请求;数字的往返结果以及两条 ValidationException 字符串,都是 DynamoDB Local 3.3.0 通过 @aws-sdk/client-dynamodb 3.1095.0 给出的原样输出,其措辞可能与线上服务不同。