DynamoDB核心概念 #
一、基本概念 #
1.1 数据模型层次 #
text
DynamoDB数据模型:
├── 表(Table)
│ └── 项目(Item)
│ └── 属性(Attribute)
│ ├── 标量类型
│ ├── 文档类型
│ └── 集合类型
1.2 概念对比 #
| 关系型数据库 | DynamoDB |
|---|---|
| 数据库 | 无(表属于AWS账户) |
| 表 | 表 |
| 行 | 项目 |
| 列 | 属性 |
| 主键 | 主键 |
| 索引 | 二级索引 |
二、表(Table) #
2.1 表的定义 #
表是DynamoDB中数据存储的基本单位,每个表包含多个项目。
text
表的特点:
├── 无需预定义Schema
├── 每个项目可以有不同的属性
├── 必须定义主键
├── 可选定义二级索引
└── 可配置容量模式
2.2 表命名规范 #
text
命名规则:
├── 长度:3-255个字符
├── 字符:a-z, A-Z, 0-9, _, -, .
├── 区分大小写
└── 同一区域内唯一
2.3 表结构示例 #
json
{
"TableName": "Users",
"KeySchema": [
{
"AttributeName": "UserId",
"KeyType": "HASH"
},
{
"AttributeName": "CreatedAt",
"KeyType": "RANGE"
}
],
"AttributeDefinitions": [
{
"AttributeName": "UserId",
"AttributeType": "S"
},
{
"AttributeName": "CreatedAt",
"AttributeType": "S"
}
],
"BillingMode": "PAY_PER_REQUEST"
}
三、项目(Item) #
3.1 项目的定义 #
项目是表中的一条数据记录,由一组属性组成。
text
项目特点:
├── 类似关系数据库的"行"
├── 最大大小:400KB
├── 必须包含主键属性
├── 其他属性可选
└── 每个项目可以有不同的属性
3.2 项目示例 #
json
{
"UserId": "user123",
"Email": "john@example.com",
"Name": "John Doe",
"Age": 30,
"CreatedAt": "2024-01-01T00:00:00Z",
"IsActive": true,
"Tags": ["premium", "verified"],
"Profile": {
"Address": {
"City": "Beijing",
"Country": "China"
},
"Phone": "+86-138-xxxx-xxxx"
}
}
3.3 属性限制 #
text
属性限制:
├── 项目总大小:最大400KB
├── 属性名称:UTF-8编码,最大64KB
├── 嵌套深度:最大32层
├── 列表/映射元素:无限制
└── 字符串:最大400KB
四、属性(Attribute) #
4.1 属性的定义 #
属性是项目中的基本数据单元,由名称和值组成。
text
属性组成:
├── 属性名称:字符串标识
└── 属性值:支持多种数据类型
4.2 属性类型 #
标量类型 #
| 类型 | 代码 | 说明 | 示例 |
|---|---|---|---|
| 字符串 | S | UTF-8字符串 | “Hello” |
| 数字 | N | 精确数值 | 123.45 |
| 二进制 | B | 二进制数据 | Base64编码 |
| 布尔 | BOOL | true/false | true |
| Null | NULL | 空值 | NULL |
文档类型 #
| 类型 | 代码 | 说明 | 示例 |
|---|---|---|---|
| 列表 | L | 有序值集合 | [1, “a”, true] |
| 映射 | M | 键值对集合 |
集合类型 #
| 类型 | 代码 | 说明 | 示例 |
|---|---|---|---|
| 字符串集 | SS | 字符串集合 | |
| 数字集 | NS | 数字集合 | |
| 二进制集 | BS | 二进制集合 |
4.3 属性示例 #
json
{
"StringAttr": "Hello World",
"NumberAttr": 123.45,
"BinaryAttr": "dGhpcyB0ZXh0IGlzIGJhc2U2NC1lbmNvZGVk",
"BooleanAttr": true,
"NullAttr": null,
"ListAttr": [1, "two", true, {"nested": "value"}],
"MapAttr": {
"name": "John",
"age": 30,
"address": {
"city": "Beijing",
"country": "China"
}
},
"StringSetAttr": ["tag1", "tag2", "tag3"],
"NumberSetAttr": [1, 2, 3, 4, 5]
}
五、主键(Primary Key) #
5.1 主键类型 #
DynamoDB支持两种主键类型:
简单主键(分区键) #
text
特点:
├── 仅由分区键组成
├── 分区键值必须唯一
└── 也称为"哈希键"
json
{
"KeySchema": [
{
"AttributeName": "UserId",
"KeyType": "HASH"
}
]
}
复合主键(分区键+排序键) #
text
特点:
├── 由分区键和排序键组成
├── 分区键+排序键组合必须唯一
├── 同一分区键下可存储多个项目
└── 排序键决定项目排序顺序
json
{
"KeySchema": [
{
"AttributeName": "UserId",
"KeyType": "HASH"
},
{
"AttributeName": "Timestamp",
"KeyType": "RANGE"
}
]
}
5.2 分区键(Partition Key) #
text
分区键作用:
├── 决定数据存储的物理分区
├── 通过哈希函数计算分区
├── 影响数据分布和性能
└── 设计原则:高基数、均匀分布
分区计算:
text
分区 = hash(分区键) % 分区数量
示例:
├── "user123" → hash → 分区1
├── "user456" → hash → 分区3
└── "user789" → hash → 分区2
5.3 排序键(Sort Key) #
text
排序键作用:
├── 同一分区内项目排序
├── 支持范围查询
├── 支持排序操作
└── 可用于高效查询设计
排序键示例:
json
[
{"PK": "USER#123", "SK": "ORDER#2024-01-01"},
{"PK": "USER#123", "SK": "ORDER#2024-01-02"},
{"PK": "USER#123", "SK": "ORDER#2024-01-03"},
{"PK": "USER#123", "SK": "PROFILE"}
]
5.4 主键设计原则 #
text
设计原则:
├── 分区键
│ ├── 高基数(大量不同值)
│ ├── 均匀分布访问
│ └── 避免热点
├── 排序键
│ ├── 支持查询模式
│ ├── 合理排序顺序
│ └── 支持范围查询
└── 组合设计
├── 满足访问模式
└── 避免过多索引
六、二级索引(Secondary Index) #
6.1 索引概述 #
text
二级索引作用:
├── 提供额外的查询模式
├── 不改变原表数据
├── 自动维护更新
└── 消耗额外容量
6.2 全局二级索引(GSI) #
text
特点:
├── 可使用任意属性作为键
├── 分区键可与表不同
├── 排序键可选
├── 跨分区查询
└── 默认最终一致性
GSI示例:
json
{
"GlobalSecondaryIndexes": [
{
"IndexName": "EmailIndex",
"KeySchema": [
{
"AttributeName": "Email",
"KeyType": "HASH"
}
],
"Projection": {
"ProjectionType": "ALL"
}
}
]
}
6.3 本地二级索引(LSI) #
text
特点:
├── 必须与表分区键相同
├── 使用不同的排序键
├── 创建表时定义
├── 同分区查询
└── 支持强一致性
LSI示例:
json
{
"LocalSecondaryIndexes": [
{
"IndexName": "CreateDateIndex",
"KeySchema": [
{
"AttributeName": "UserId",
"KeyType": "HASH"
},
{
"AttributeName": "CreateDate",
"KeyType": "RANGE"
}
],
"Projection": {
"ProjectionType": "ALL"
}
}
]
}
6.4 索引对比 #
| 特性 | GSI | LSI |
|---|---|---|
| 分区键 | 可不同 | 必须相同 |
| 创建时机 | 任何时候 | 创建表时 |
| 数量限制 | 20个/表 | 5个/表 |
| 项目大小限制 | 无限制 | 400KB |
| 一致性 | 最终一致 | 强一致/最终一致 |
| 容量消耗 | 独立配置 | 共享表容量 |
七、容量模式 #
7.1 按需模式 #
text
特点:
├── 按请求计费
├── 自动扩展
├── 无需容量规划
└── 适合不可预测流量
7.2 预置模式 #
text
特点:
├── 预先配置容量单位
├── 可预测成本
├── 支持Auto Scaling
└── 适合可预测流量
7.3 容量单位 #
| 单位 | 说明 |
|---|---|
| RCU | 读取容量单位 |
| WCU | 写入容量单位 |
RCU计算:
text
1 RCU = 1次强一致性读取(4KB)
1 RCU = 2次最终一致性读取(4KB)
示例:
├── 读取8KB项目(强一致)= 2 RCU
├── 读取8KB项目(最终一致)= 1 RCU
└── 读取1KB项目 = 0.25 RCU(向上取整为1)
WCU计算:
text
1 WCU = 1次写入(1KB)
示例:
├── 写入5KB项目 = 5 WCU
├── 写入0.5KB项目 = 1 WCU
└── 写入10KB项目 = 10 WCU
八、一致性模型 #
8.1 最终一致性 #
text
特点:
├── 默认模式
├── 读取可能不是最新数据
├── 延迟通常<1秒
├── 消耗较少RCU
└── 适合大多数场景
8.2 强一致性 #
text
特点:
├── 返回最新数据
├── 消耗更多RCU
├── 延迟略高
└── 适合需要实时数据的场景
8.3 一致性选择 #
text
选择建议:
├── 最终一致性
│ ├── 社交媒体动态
│ ├── 产品目录
│ └── 统计分析
└── 强一致性
├── 金融交易
├── 库存管理
└── 用户认证
九、数据分布 #
9.1 分区机制 #
text
数据分布过程:
├── 1. 计算分区键哈希值
├── 2. 映射到物理分区
├── 3. 数据存储在对应分区
└── 4. 自动平衡分区负载
9.2 热点问题 #
text
热点原因:
├── 分区键基数低
├── 访问模式不均匀
├── 时间序列数据
└── 热门项目集中
解决方案:
├── 添加随机后缀
├── 使用复合键
├── 分散写入
└── 合理设计分区键
9.3 分区键设计示例 #
json
{
"BadDesign": {
"PK": "STATUS#ACTIVE",
"description": "所有活跃用户在同一分区"
},
"GoodDesign": {
"PK": "USER#12345",
"description": "用户ID分散到不同分区"
},
"TimeSeriesDesign": {
"PK": "DEVICE#SENSOR001#2024-01-01",
"SK": "TIMESTAMP#1704067200",
"description": "按日期分散时间序列数据"
}
}
十、总结 #
核心概念要点:
| 概念 | 要点 |
|---|---|
| 表 | 数据存储的基本单位 |
| 项目 | 一条数据记录,最大400KB |
| 属性 | 数据字段,支持多种类型 |
| 主键 | 唯一标识项目 |
| 分区键 | 决定数据分布 |
| 排序键 | 决定排序和范围查询 |
| 二级索引 | 提供额外查询模式 |
下一步,让我们学习DynamoDB CLI的使用!
最后更新:2026-03-27