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