DynamoDB表操作 #
一、表操作概述 #
1.1 表的生命周期 #
text
表生命周期:
├── 创建(Create)
│ ├── 定义主键
│ ├── 配置容量
│ └── 创建索引
├── 使用(Use)
│ ├── 读写数据
│ └── 查询操作
├── 修改(Update)
│ ├── 调整容量
│ ├── 添加索引
│ └── 启用功能
└── 删除(Delete)
└── 清理资源
1.2 表的限制 #
| 限制项 | 值 |
|---|---|
| 表名长度 | 3-255字符 |
| 表名规则 | a-z, A-Z, 0-9, _, -, . |
| 每区域表数量 | 默认256个 |
| 每表索引数量 | GSI: 20个, LSI: 5个 |
| 项目大小 | 最大400KB |
二、创建表 #
2.1 基本创建 #
使用AWS CLI:
bash
aws dynamodb create-table \
--table-name Users \
--attribute-definitions \
AttributeName=UserId,AttributeType=S \
--key-schema \
AttributeName=UserId,KeyType=HASH \
--billing-mode PAY_PER_REQUEST
使用JavaScript SDK:
javascript
const { DynamoDBClient, CreateTableCommand } = require('@aws-sdk/client-dynamodb');
const client = new DynamoDBClient({ region: 'us-east-1' });
const command = new CreateTableCommand({
TableName: 'Users',
AttributeDefinitions: [
{ AttributeName: 'UserId', AttributeType: 'S' }
],
KeySchema: [
{ AttributeName: 'UserId', KeyType: 'HASH' }
],
BillingMode: 'PAY_PER_REQUEST'
});
await client.send(command);
使用Python SDK:
python
import boto3
dynamodb = boto3.resource('dynamodb')
table = dynamodb.create_table(
TableName='Users',
KeySchema=[
{'AttributeName': 'UserId', 'KeyType': 'HASH'}
],
AttributeDefinitions=[
{'AttributeName': 'UserId', 'AttributeType': 'S'}
],
BillingMode='PAY_PER_REQUEST'
)
table.wait_until_exists()
2.2 复合主键表 #
bash
aws dynamodb create-table \
--table-name Orders \
--attribute-definitions \
AttributeName=UserId,AttributeType=S \
AttributeName=OrderId,AttributeType=S \
--key-schema \
AttributeName=UserId,KeyType=HASH \
AttributeName=OrderId,KeyType=RANGE \
--billing-mode PAY_PER_REQUEST
javascript
const command = new CreateTableCommand({
TableName: 'Orders',
AttributeDefinitions: [
{ AttributeName: 'UserId', AttributeType: 'S' },
{ AttributeName: 'OrderId', AttributeType: 'S' }
],
KeySchema: [
{ AttributeName: 'UserId', KeyType: 'HASH' },
{ AttributeName: 'OrderId', KeyType: 'RANGE' }
],
BillingMode: 'PAY_PER_REQUEST'
});
2.3 预置容量模式 #
bash
aws dynamodb create-table \
--table-name Products \
--attribute-definitions \
AttributeName=ProductId,AttributeType=S \
--key-schema \
AttributeName=ProductId,KeyType=HASH \
--provisioned-throughput \
ReadCapacityUnits=10,WriteCapacityUnits=5
javascript
const command = new CreateTableCommand({
TableName: 'Products',
AttributeDefinitions: [
{ AttributeName: 'ProductId', AttributeType: 'S' }
],
KeySchema: [
{ AttributeName: 'ProductId', KeyType: 'HASH' }
],
ProvisionedThroughput: {
ReadCapacityUnits: 10,
WriteCapacityUnits: 5
}
});
2.4 带全局二级索引 #
bash
aws dynamodb create-table \
--table-name Users \
--attribute-definitions \
AttributeName=UserId,AttributeType=S \
AttributeName=Email,AttributeType=S \
--key-schema \
AttributeName=UserId,KeyType=HASH \
--global-secondary-indexes \
'[
{
"IndexName": "EmailIndex",
"KeySchema": [
{"AttributeName": "Email", "KeyType": "HASH"}
],
"Projection": {"ProjectionType": "ALL"},
"ProvisionedThroughput": {
"ReadCapacityUnits": 5,
"WriteCapacityUnits": 5
}
}
]' \
--billing-mode PAY_PER_REQUEST
javascript
const command = new CreateTableCommand({
TableName: 'Users',
AttributeDefinitions: [
{ AttributeName: 'UserId', AttributeType: 'S' },
{ AttributeName: 'Email', AttributeType: 'S' }
],
KeySchema: [
{ AttributeName: 'UserId', KeyType: 'HASH' }
],
GlobalSecondaryIndexes: [
{
IndexName: 'EmailIndex',
KeySchema: [
{ AttributeName: 'Email', KeyType: 'HASH' }
],
Projection: { ProjectionType: 'ALL' }
}
],
BillingMode: 'PAY_PER_REQUEST'
});
2.5 带本地二级索引 #
bash
aws dynamodb create-table \
--table-name Orders \
--attribute-definitions \
AttributeName=UserId,AttributeType=S \
AttributeName=OrderId,AttributeType=S \
AttributeName=OrderDate,AttributeType=S \
--key-schema \
AttributeName=UserId,KeyType=HASH \
AttributeName=OrderId,KeyType=RANGE \
--local-secondary-indexes \
'[
{
"IndexName": "OrderDateIndex",
"KeySchema": [
{"AttributeName": "UserId", "KeyType": "HASH"},
{"AttributeName": "OrderDate", "KeyType": "RANGE"}
],
"Projection": {"ProjectionType": "ALL"}
}
]' \
--billing-mode PAY_PER_REQUEST
2.6 带流配置 #
bash
aws dynamodb create-table \
--table-name Events \
--attribute-definitions \
AttributeName=EventId,AttributeType=S \
--key-schema \
AttributeName=EventId,KeyType=HASH \
--billing-mode PAY_PER_REQUEST \
--stream-specification \
StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES
StreamViewType选项:
| 类型 | 说明 |
|---|---|
| KEYS_ONLY | 仅记录键 |
| NEW_IMAGE | 仅新值 |
| OLD_IMAGE | 仅旧值 |
| NEW_AND_OLD_IMAGES | 新旧值都记录 |
2.7 带加密配置 #
bash
aws dynamodb create-table \
--table-name SensitiveData \
--attribute-definitions \
AttributeName=Id,AttributeType=S \
--key-schema \
AttributeName=Id,KeyType=HASH \
--billing-mode PAY_PER_REQUEST \
--sse-specification \
Enabled=true,SSEType=KMS,KMSMasterKeyId=alias/my-key
SSEType选项:
| 类型 | 说明 |
|---|---|
| AES256 | 默认加密 |
| KMS | KMS托管密钥 |
三、查看表信息 #
3.1 描述表 #
bash
aws dynamodb describe-table \
--table-name Users
返回信息:
json
{
"Table": {
"TableName": "Users",
"TableStatus": "ACTIVE",
"CreationDateTime": "2024-01-01T00:00:00.000Z",
"TableArn": "arn:aws:dynamodb:us-east-1:123456789012:table/Users",
"TableSizeBytes": 1024,
"ItemCount": 100,
"KeySchema": [
{
"AttributeName": "UserId",
"KeyType": "HASH"
}
],
"AttributeDefinitions": [
{
"AttributeName": "UserId",
"AttributeType": "S"
}
],
"BillingModeSummary": {
"BillingMode": "PAY_PER_REQUEST"
}
}
}
3.2 列出所有表 #
bash
# 列出所有表
aws dynamodb list-tables
# 分页列出
aws dynamodb list-tables \
--limit 10 \
--exclusive-start-table-name <last-table-name>
3.3 查询特定信息 #
bash
# 查看表状态
aws dynamodb describe-table \
--table-name Users \
--query 'Table.TableStatus' \
--output text
# 查看表ARN
aws dynamodb describe-table \
--table-name Users \
--query 'Table.TableArn' \
--output text
# 查看项目数量
aws dynamodb describe-table \
--table-name Users \
--query 'Table.ItemCount'
# 查看索引
aws dynamodb describe-table \
--table-name Users \
--query 'Table.GlobalSecondaryIndexes'
四、更新表 #
4.1 更新容量 #
bash
# 更新预置容量
aws dynamodb update-table \
--table-name Products \
--provisioned-throughput \
ReadCapacityUnits=20,WriteCapacityUnits=10
javascript
const command = new UpdateTableCommand({
TableName: 'Products',
ProvisionedThroughput: {
ReadCapacityUnits: 20,
WriteCapacityUnits: 10
}
});
4.2 添加全局二级索引 #
bash
aws dynamodb update-table \
--table-name Users \
--attribute-definitions \
AttributeName=Phone,AttributeType=S \
--global-secondary-index-updates \
'[
{
"Create": {
"IndexName": "PhoneIndex",
"KeySchema": [
{"AttributeName": "Phone", "KeyType": "HASH"}
],
"Projection": {"ProjectionType": "ALL"}
}
}
]'
4.3 删除全局二级索引 #
bash
aws dynamodb update-table \
--table-name Users \
--global-secondary-index-updates \
'[
{
"Delete": {
"IndexName": "PhoneIndex"
}
}
]'
4.4 更新索引容量 #
bash
aws dynamodb update-table \
--table-name Users \
--global-secondary-index-updates \
'[
{
"Update": {
"IndexName": "EmailIndex",
"ProvisionedThroughput": {
"ReadCapacityUnits": 10,
"WriteCapacityUnits": 5
}
}
}
]'
4.5 启用TTL #
bash
aws dynamodb update-time-to-live \
--table-name Sessions \
--time-to-live-specification \
Enabled=true,AttributeName=ExpirationTime
4.6 启用流 #
bash
aws dynamodb update-table \
--table-name Events \
--stream-specification \
StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES
4.7 等待表状态 #
bash
# 等待表创建完成
aws dynamodb wait table-exists \
--table-name Users
# 等待表删除完成
aws dynamodb wait table-not-exists \
--table-name Users
五、删除表 #
5.1 基本删除 #
bash
aws dynamodb delete-table \
--table-name Users
javascript
const command = new DeleteTableCommand({
TableName: 'Users'
});
python
dynamodb.Table('Users').delete()
5.2 确认删除 #
bash
# 删除表
aws dynamodb delete-table --table-name Users
# 等待删除完成
aws dynamodb wait table-not-exists --table-name Users
# 确认删除
aws dynamodb describe-table --table-name Users 2>&1 | grep "Requested resource not found"
六、表配置详解 #
6.1 容量模式选择 #
| 模式 | 特点 | 适用场景 |
|---|---|---|
| 按需模式 | 自动扩展,按请求计费 | 流量不可预测 |
| 预置模式 | 固定容量,可预测成本 | 流量可预测 |
按需模式:
bash
--billing-mode PAY_PER_REQUEST
预置模式:
bash
--provisioned-throughput \
ReadCapacityUnits=10,WriteCapacityUnits=5
6.2 投影类型 #
| 类型 | 说明 | 存储成本 |
|---|---|---|
| KEYS_ONLY | 仅索引键 | 最低 |
| INCLUDE | 键+指定属性 | 中等 |
| ALL | 所有属性 | 最高 |
json
{
"Projection": {
"ProjectionType": "INCLUDE",
"NonKeyAttributes": ["Name", "Email"]
}
}
6.3 标签管理 #
bash
# 添加标签
aws dynamodb tag-resource \
--resource-arn arn:aws:dynamodb:us-east-1:123456789012:table/Users \
--tags Key=Environment,Value=Production Key=Project,Value=MyApp
# 查看标签
aws dynamodb list-tags-of-resource \
--resource-arn arn:aws:dynamodb:us-east-1:123456789012:table/Users
# 删除标签
aws dynamodb untag-resource \
--resource-arn arn:aws:dynamodb:us-east-1:123456789012:table/Users \
--tag-keys Environment
七、CloudFormation创建 #
7.1 基本模板 #
yaml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
UsersTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: Users
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: UserId
AttributeType: S
KeySchema:
- AttributeName: UserId
KeyType: HASH
Tags:
- Key: Environment
Value: Production
7.2 带GSI的模板 #
yaml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
OrdersTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: Orders
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: UserId
AttributeType: S
- AttributeName: OrderId
AttributeType: S
- AttributeName: OrderDate
AttributeType: S
KeySchema:
- AttributeName: UserId
KeyType: HASH
- AttributeName: OrderId
KeyType: RANGE
GlobalSecondaryIndexes:
- IndexName: OrderDateIndex
KeySchema:
- AttributeName: OrderDate
KeyType: HASH
Projection:
ProjectionType: ALL
StreamSpecification:
StreamViewType: NEW_AND_OLD_IMAGES
八、最佳实践 #
8.1 命名规范 #
text
命名建议:
├── 使用描述性名称
├── 使用统一前缀(环境/项目)
├── 避免使用保留字
└── 示例:
├── dev-Users
├── prod-Orders
└── staging-Products
8.2 容量规划 #
text
容量规划建议:
├── 按需模式
│ ├── 开发/测试环境
│ ├── 流量不可预测
│ └── 初期项目
└── 预置模式
├── 生产环境(流量稳定)
├── 成本敏感场景
└── 配合Auto Scaling
8.3 索引设计 #
text
索引设计建议:
├── 仅创建必要的索引
├── 合理选择投影类型
├── 考虑稀疏索引
└── 监控索引使用情况
九、常见问题 #
9.1 表创建失败 #
text
常见原因:
├── 表名已存在
├── 属性定义与键模式不匹配
├── 超过区域表数量限制
└── IAM权限不足
9.2 表状态检查 #
bash
# 检查表状态
aws dynamodb describe-table \
--table-name Users \
--query 'Table.TableStatus'
# 状态值:
# CREATING - 创建中
# UPDATING - 更新中
# DELETING - 删除中
# ACTIVE - 活跃
9.3 等待表就绪 #
javascript
async function waitForTableActive(tableName) {
const client = new DynamoDBClient();
while (true) {
const response = await client.send(
new DescribeTableCommand({ TableName: tableName })
);
if (response.Table.TableStatus === 'ACTIVE') {
return response.Table;
}
await new Promise(resolve => setTimeout(resolve, 1000));
}
}
十、总结 #
表操作要点:
| 操作 | 命令 | 说明 |
|---|---|---|
| 创建表 | create-table | 定义主键和配置 |
| 查看表 | describe-table | 获取表详情 |
| 列出表 | list-tables | 列出所有表 |
| 更新表 | update-table | 修改配置 |
| 删除表 | delete-table | 删除表 |
下一步,让我们学习表设计最佳实践!
最后更新:2026-03-27