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