DynamoDB's single-table design pattern enables high performance at scale, but requires rethinking how you model data compared to relational databases.
Core Concepts
- Partition Key (PK): distributes data across nodes — must be high cardinality
- Sort Key (SK): enables range queries within a partition
- GSI: Global Secondary Index — alternate access patterns with different PK/SK
- LSI: Local Secondary Index — alternate SK, same PK (must be defined at table creation)
Single-Table Design
PK SK Attributes
USER#123 PROFILE name, email, created_at
USER#123 ORDER#2025-001 amount, status
USER#123 ORDER#2025-002 amount, status
ORDER#2025-001 ITEM#prod-A quantity, price
ORDER#2025-001 ITEM#prod-B quantity, priceOne table holds users, orders, and order items. Access patterns map directly to PK/SK queries.
Common Access Patterns
import boto3
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('MyTable')
# Get user profile
table.get_item(Key={'PK': 'USER#123', 'SK': 'PROFILE'})
# Get all orders for user (SK begins_with)
table.query(
KeyConditionExpression='PK = :pk AND begins_with(SK, :prefix)',
ExpressionAttributeValues={':pk': 'USER#123', ':prefix': 'ORDER#'}
)
# Get specific order
table.get_item(Key={'PK': 'USER#123', 'SK': 'ORDER#2025-001'})Global Secondary Index for Reverse Lookup
{
"GlobalSecondaryIndexes": [{
"IndexName": "GSI1",
"KeySchema": [
{"AttributeName": "GSI1PK", "KeyType": "HASH"},
{"AttributeName": "GSI1SK", "KeyType": "RANGE"}
],
"Projection": {"ProjectionType": "ALL"}
}]
}GSI1PK GSI1SK Use case
STATUS#pending ORDER#2025-001 All pending orders
EMAIL#user@ex.com USER#123 User lookup by emailCapacity Planning
- On-demand: no planning needed, pay per request — best for variable/unpredictable traffic
- Provisioned + Auto Scaling: set min/max RCU/WCU — better for steady predictable load
# Monitor consumed capacity
aws cloudwatch get-metric-statistics \
--namespace AWS/DynamoDB \
--metric-name ConsumedReadCapacityUnits \
--dimensions Name=TableName,Value=MyTable \
--statistics Sum --period 60Key Takeaways
- Single-table design puts all entity types in one table — access patterns drive schema
- Use composite SK values (
ORDER#2025-001) to enable range queries within a partition - GSIs add access patterns — plan them up front since GSI data is eventually consistent
- Use on-demand capacity for new applications; switch to provisioned + auto scaling after load stabilizes
JusDB Can Help
DynamoDB single-table design requires up-front access pattern analysis. JusDB can model your data for DynamoDB and avoid costly re-migrations.