DynamoDB #

一、DynamoDB概述 #

1.1 什么是DynamoDB #

Amazon DynamoDB是AWS提供的完全托管的NoSQL数据库服务,提供快速、可预测的性能和无缝扩展能力。

1.2 DynamoDB特点 #

text
DynamoDB核心特点:
├── 完全托管
│   ├── 无服务器
│   ├── 自动扩展
│   └── 无需管理基础设施
│
├── 高性能
│   ├── 毫秒级延迟
│   └── 可预测的性能
│
├── 无限扩展
│   ├── 自动分区
│   └── 无容量限制
│
├── 高可用
│   ├── 跨3个可用区
│   └── 99.99%可用性
│
├── 灵活
│   ├── 无模式
│   └── 支持嵌套属性
│
└── 安全
    ├── 加密
    └── IAM授权

1.3 DynamoDB使用场景 #

场景 说明
用户配置文件 存储用户信息和设置
会话存储 Web应用会话管理
游戏数据 游戏状态和排行榜
物联网数据 设备数据和事件
电商购物车 购物车和订单
日志和事件 应用日志和事件流

二、核心概念 #

2.1 表、项目和属性 #

text
DynamoDB数据模型:
├── 表(Table)
│   └── 数据的集合
│   └── 类似关系数据库的表
│
├── 项目(Item)
│   └── 表中的一条记录
│   └── 类似关系数据库的行
│   └── 最大400KB
│
└── 属性(Attribute)
    └── 项目中的数据字段
    └── 类似关系数据库的列
    └── 支持多种数据类型

2.2 主键 #

text
主键类型:
├── 分区键(Partition Key)
│   └── 单属性主键
│   └── 根据分区键值进行哈希分区
│
└── 复合主键(Composite Key)
    ├── 分区键 + 排序键(Sort Key)
    ├── 分区键决定分区
    └── 排序键决定排序

2.3 数据类型 #

text
DynamoDB数据类型:
├── 标量类型
│   ├── String (S)
│   ├── Number (N)
│   ├── Binary (B)
│   └── Boolean (BOOL)
│
├── 文档类型
│   ├── Map (M)
│   └── List (L)
│
└── 集合类型
    ├── String Set (SS)
    ├── Number Set (NS)
    └── Binary Set (BS)

2.4 示例项目 #

json
{
    "UserId": "user123",
    "Timestamp": 1704067200,
    "Email": "user@example.com",
    "Name": "John Doe",
    "Age": 30,
    "IsActive": true,
    "Preferences": {
        "Theme": "dark",
        "Language": "en"
    },
    "Tags": ["premium", "verified"]
}

三、创建表 #

3.1 通过控制台创建 #

text
创建表步骤:
├── 第一步:表名称
│   └── 输入表名
│
├── 第二步:主键
│   ├── 分区键
│   └── 排序键(可选)
│
├── 第三步:表设置
│   ├── 自定义设置
│   └── 默认设置
│
├── 第四步:容量模式
│   ├── 按需模式
│   └── 预置模式
│
└── 第五步:创建表

3.2 通过CLI创建 #

bash
aws dynamodb create-table \
    --table-name Users \
    --attribute-definitions \
        AttributeName=UserId,AttributeType=S \
        AttributeName=Timestamp,AttributeType=N \
    --key-schema \
        AttributeName=UserId,KeyType=HASH \
        AttributeName=Timestamp,KeyType=RANGE \
    --billing-mode PAY_PER_REQUEST

3.3 容量模式 #

text
容量模式:
├── 按需模式(On-Demand)
│   ├── 自动扩展
│   ├── 按请求付费
│   ├── 适合不可预测流量
│   └── 成本较高
│
└── 预置模式(Provisioned)
    ├── 指定RCU/WCU
    ├── 可配置自动扩展
    ├── 适合可预测流量
    └── 成本较低

3.4 容量单位 #

text
读写容量单位:
├── 读容量单位(RCU)
│   ├── 1 RCU = 1次强一致性读取/秒(4KB)
│   └── 1 RCU = 2次最终一致性读取/秒(4KB)
│
└── 写容量单位(WCU)
    └── 1 WCU = 1次写入/秒(1KB)

四、数据操作 #

4.1 写入数据 #

PutItem #

bash
aws dynamodb put-item \
    --table-name Users \
    --item '{
        "UserId": {"S": "user123"},
        "Email": {"S": "user@example.com"},
        "Name": {"S": "John Doe"},
        "Age": {"N": "30"}
    }'

Python示例 #

python
import boto3

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('Users')

table.put_item(
    Item={
        'UserId': 'user123',
        'Email': 'user@example.com',
        'Name': 'John Doe',
        'Age': 30
    }
)

4.2 读取数据 #

GetItem #

bash
aws dynamodb get-item \
    --table-name Users \
    --key '{"UserId": {"S": "user123"}}'

Python示例 #

python
response = table.get_item(
    Key={
        'UserId': 'user123'
    }
)
item = response['Item']
print(item)

4.3 更新数据 #

bash
aws dynamodb update-item \
    --table-name Users \
    --key '{"UserId": {"S": "user123"}}' \
    --update-expression "SET Age = :age" \
    --expression-attribute-values '{":age": {"N": "31"}}'
python
table.update_item(
    Key={
        'UserId': 'user123'
    },
    UpdateExpression='SET Age = :age',
    ExpressionAttributeValues={
        ':age': 31
    }
)

4.4 删除数据 #

bash
aws dynamodb delete-item \
    --table-name Users \
    --key '{"UserId": {"S": "user123"}}'
python
table.delete_item(
    Key={
        'UserId': 'user123'
    }
)

4.5 批量操作 #

python
with table.batch_writer() as batch:
    for i in range(100):
        batch.put_item(
            Item={
                'UserId': f'user{i}',
                'Name': f'User {i}'
            }
        )

五、查询和扫描 #

5.1 Query #

Query用于高效查询:

bash
aws dynamodb query \
    --table-name Users \
    --key-condition-expression "UserId = :uid" \
    --expression-attribute-values '{":uid": {"S": "user123"}}'
python
response = table.query(
    KeyConditionExpression=Key('UserId').eq('user123')
)
items = response['Items']

5.2 Scan #

Scan扫描整个表:

bash
aws dynamodb scan \
    --table-name Users \
    --filter-expression "Age > :age" \
    --expression-attribute-values '{":age": {"N": "25"}}'
python
response = table.scan(
    FilterExpression=Attr('Age').gt(25)
)
items = response['Items']

5.3 Query vs Scan #

特性 Query Scan
效率
消耗 只读取匹配项 扫描全表
条件 必须指定分区键 可任意过滤
用途 主键查询 全表搜索

六、索引 #

6.1 本地二级索引(LSI) #

text
LSI特点:
├── 与表共享分区键
├── 不同的排序键
├── 创建表时定义
├── 每个表最多5个
└── 项目集合大小限制

6.2 全局二级索引(GSI) #

text
GSI特点:
├── 可有不同的分区键和排序键
├── 可随时创建
├── 每个表默认20个(可提升)
├── 独立的吞吐量
└── 更灵活

6.3 创建GSI #

bash
aws dynamodb update-table \
    --table-name Users \
    --attribute-definitions AttributeName=Email,AttributeType=S \
    --global-secondary-index-updates \
        '[{
            "Create": {
                "IndexName": "EmailIndex",
                "KeySchema": [{"AttributeName": "Email", "KeyType": "HASH"}],
                "Projection": {"ProjectionType": "ALL"}
            }
        }]'

6.4 使用索引查询 #

python
response = table.query(
    IndexName='EmailIndex',
    KeyConditionExpression=Key('Email').eq('user@example.com')
)

七、DynamoDB Streams #

7.1 Streams概述 #

text
Streams特点:
├── 捕获表的变更事件
├── 按时间顺序记录
├── 24小时保留
├── 可触发Lambda
└── 支持多种视图类型

7.2 启用Streams #

bash
aws dynamodb update-table \
    --table-name Users \
    --stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES

7.3 视图类型 #

视图类型 说明
KEYS_ONLY 仅主键
NEW_IMAGE 新项目
OLD_IMAGE 旧项目
NEW_AND_OLD_IMAGES 新旧项目

7.4 Lambda触发器 #

python
def lambda_handler(event, context):
    for record in event['Records']:
        if record['eventName'] == 'INSERT':
            print(f"New item: {record['dynamodb']['NewImage']}")
        elif record['eventName'] == 'MODIFY':
            print(f"Modified item: {record['dynamodb']['NewImage']}")
        elif record['eventName'] == 'REMOVE':
            print(f"Removed item: {record['dynamodb']['OldImage']}")

八、DynamoDB最佳实践 #

8.1 表设计 #

text
表设计建议:
├── 选择合适的主键
│   ├── 高基数的分区键
│   └── 避免热点分区
│
├── 使用复合主键
│   └── 支持排序查询
│
├── 使用GSI
│   └── 支持非主键查询
│
└── 单表设计
    └── 减少表数量

8.2 性能优化 #

text
性能建议:
├── 避免热分区
│   └── 分散写入
│
├── 使用投影
│   └── 只返回需要的属性
│
├── 批量操作
│   └── 减少请求次数
│
├── 并行扫描
│   └── 加速全表扫描
│
└── 使用缓存
    └── DAX加速读取

8.3 成本优化 #

text
成本优化建议:
├── 选择合适的容量模式
├── 使用投影减少读取
├── 删除不需要的数据
├── 监控容量使用
└── 使用自动扩展

九、DynamoDB Accelerator (DAX) #

9.1 DAX概述 #

text
DAX特点:
├── 内存缓存
├── 微秒级延迟
├── 与DynamoDB API兼容
├── 自动缓存失效
└── 适合读密集型工作负载

9.2 使用DAX #

python
import boto3
from amazondax import AmazonDaxClient

dax = AmazonDaxClient(
    endpoint_url='dax://my-cluster.xxxxx.dax-clusters.us-east-1.amazonaws.com'
)
table = dax.Table('Users')

十、小结 #

本章介绍了DynamoDB:

内容 要点
DynamoDB概念 NoSQL数据库、无服务器
数据模型 表、项目、属性
主键 分区键、复合主键
索引 LSI、GSI
Streams 变更事件捕获

下一步学习 #

了解DynamoDB后,接下来可以:

  1. Aurora - 学习云原生数据库
  2. 无服务器应用 - 实践DynamoDB应用
  3. Lambda无服务器 - DynamoDB Streams触发Lambda
最后更新:2026-03-28