AWS DynamoDB는 AWS의 완전 관리형 NoSQL 키-값 및 문서 데이터베이스로, 어떤 규모에서도 한 자릿수 밀리초 성능을 제공한다. 서버리스로 운영되며 자동 스케일링을 지원한다.
DynamoDB 핵심 개념
| 개념 | 설명 |
|---|
| 파티션 키 | 데이터 분산 기준 (필수) |
| 정렬 키 | 같은 파티션 내 정렬 (선택) |
| LSI | 같은 파티션 키, 다른 정렬 키 인덱스 |
| GSI | 다른 파티션/정렬 키 인덱스 (별도 용량) |
| RCU/WCU | 읽기/쓰기 용량 단위 |
테이블 설계 예시
python
import boto3
from boto3.dynamodb.conditions import Key, Attr
dynamodb = boto3.resource('dynamodb', region_name='ap-northeast-2')
# 테이블 생성
table = dynamodb.create_table(
TableName='Orders',
KeySchema=[
{'AttributeName': 'PK', 'KeyType': 'HASH'}, # 파티션 키
{'AttributeName': 'SK', 'KeyType': 'RANGE'}, # 정렬 키
],
AttributeDefinitions=[
{'AttributeName': 'PK', 'AttributeType': 'S'},
{'AttributeName': 'SK', 'AttributeType': 'S'},
{'AttributeName': 'GSI1PK', 'AttributeType': 'S'},
],
GlobalSecondaryIndexes=[{
'IndexName': 'GSI1',
'KeySchema': [
{'AttributeName': 'GSI1PK', 'KeyType': 'HASH'},
],
'Projection': {'ProjectionType': 'ALL'},
}],
BillingMode='PAY_PER_REQUEST',
)
Single-Table 설계 패턴
python
# 한 테이블에 여러 엔티티 유형 저장 (Single-Table Design)
# PK=USER#userId, SK=PROFILE → 사용자 프로필
# PK=USER#userId, SK=ORDER#orderId → 사용자 주문
# PK=ORDER#orderId, SK=ITEM#itemId → 주문 항목
def put_user(table, user_id: str, name: str, email: str):
table.put_item(Item={
'PK': f'USER#{user_id}',
'SK': 'PROFILE',
'GSI1PK': f'EMAIL#{email}',
'name': name,
'email': email,
'createdAt': today,
})
def get_user_orders(table, user_id: str):
response = table.query(
KeyConditionExpression=Key('PK').eq(f'USER#{user_id}') &
Key('SK').begins_with('ORDER#')
)
return response['Items']
DynamoDB Streams + Lambda
python
# Lambda 트리거: 주문 생성 시 재고 업데이트
def handler(event, context):
for record in event['Records']:
if record['eventName'] == 'INSERT':
new_item = record['dynamodb']['NewImage']
if new_item['SK']['S'].startswith('ORDER#'):
update_inventory(new_item)
def update_inventory(order):
table = dynamodb.Table('Inventory')
table.update_item(
Key={'ProductId': order['productId']['S']},
UpdateExpression='SET stock = stock - :qty',
ExpressionAttributeValues={':qty': int(order['quantity']['N'])},
ConditionExpression=Attr('stock').gte(int(order['quantity']['N'])),
)
DynamoDB vs 다른 DB
| 항목 | DynamoDB | RDS | MongoDB |
|---|
| 운영 | 완전 관리형 | 부분 관리 | 자체 관리 |
| 확장성 | 무한 자동 | 수직/읽기 복제 | 수평 샤딩 |
| 일관성 | 최종/강한 선택 | 강한 일관성 | 설정 가능 |
| 쿼리 유연성 | 제한적 | SQL 풍부 | 풍부 |
| 비용 모델 | 요청/용량 기반 | 인스턴스 기반 | 인스턴스 기반 |