DynamoDB 복합 기본 키
복합 기본 키는 두 개의 속성입니다: 파티션 키와 정렬 키. 파티션 키는 아이템이 어디에 사는지를 결정하고, 정렬 키는 그 파티션 안에서 아이템을 정렬합니다.
SQL에서 넘어왔다면, 고유한 id 컬럼이라기보다는 테이블 자체에 구워 넣은
GROUP BY partition, ORDER BY sort로 생각하세요.
DynamoDB 복합 기본 키란 무엇인가요?
DynamoDB 복합 기본 키는 두 개의 속성을 결합합니다: 파티션 키와 정렬 키. 파티션 키는 아이템이 어느 물리 파티션에 저장될지를 결정하고, 정렬 키는 그 파티션 안에서 아이템을 정렬합니다. 이 둘이 함께 아이템의 고유한 식별자를 이루며, 하나의 Query가 단일 아이템이 아니라 정렬된 범위를 반환할 수 있게 합니다.
- 두 부분, 두 역할. 파티션 키는 아이템을 물리 파티션으로 라우팅하고, 정렬 키는 그 파티션 키를 공유하는 모든 아이템을 정렬합니다.
- 고유성은 그 쌍입니다. 두 아이템은 정렬 키가 다르기만 하면 파티션 키 값을 공유할 수 있습니다 — 그것이 하나의 파티션이 여러 행을 담는 방식입니다.
- 정렬 키가 핵심 전부입니다. 그것이
Query로 하나의 아이템이 아니라 범위 (>=,between,begins_with)를 —Scan없이 — 반환하게 합니다. - 키는 스칼라여야 합니다. 파티션 키와 정렬 키는 문자열, 숫자, 또는 바이너리만 될 수 있습니다 — 맵도 리스트도 안 됩니다 (AWS 문서).
단순 키 vs 복합 키
단순 기본 키는 파티션 키뿐입니다. 아이템을 고유하게 식별하며, GetItem으로 읽어
들입니다. 그게 다입니다 — 범위 읽기도, "최신 N개를 줘"도 없습니다.
복합 키는 정렬 키를 더하며, 그 단 하나의 추가가 DynamoDB를 해시 맵이 아니라 데이터베이스처럼 느끼게 만드는 것입니다.
| 단순 키 | 복합 키 | |
|---|---|---|
| 속성 | 파티션 키만 | 파티션 키 + 정렬 키 |
| 고유성 | 파티션 키 값 | 값의 쌍 |
| 파티션당 여러 아이템 | 아니오 | 예 |
Query 범위 | 아니오 (GetItem만) | 예 (begins_with, between, >) |
| 자연스러운 적합 | id로 조회 | 시계열, 일대다, 이력 |
센서 측정값 테이블 모델링
현장 센서 무리에서 온도 샘플을 수집한다고 합시다. 액세스 패턴은 "한 디바이스의 측정값을, 최신 순으로, 시간 범위 내에서 가져오기"입니다. 그것은 교과서적인 복합 키입니다.
디바이스 id를 파티션 키로, 측정 타임스탬프를 정렬 키로 쓰세요:
| deviceId | readingTs | tempC | humidity |
|---|---|---|---|
| DEV#a1b2 | 2026-06-23T08:00:00Z | 21.4 | 48 |
| DEV#a1b2 | 2026-06-23T08:05:00Z | 21.7 | 47 |
| DEV#a1b2 | 2026-06-23T08:10:00Z | 22.1 | 46 |
| DEV#c9d8 | 2026-06-23T08:00:00Z | 19.8 | 55 |
세 개의 DEV#a1b2 측정값은 모두 같은 파티션에 떨어지고, 물리적으로 함께 저장되며,
readingTs로 정렬됩니다.
AWS는 파티션 키를 해시 속성, 정렬 키를 범위 속성이라 부릅니다 — 정렬 키는 그 안에서 스캔할 수 있는 범위입니다 (AWS 문서).
각 파티션 키 아래에서 아이템이 하나의 아이템 컬렉션으로 모이는 모습은 이렇습니다:
파티션 키에 대한 하나의 Query가 그 디바이스의 모든 측정값을 — 이미 타임스탬프 순으로 —
읽습니다. 클라이언트 쪽 정렬도, 두 번째 왕복도 없이.
범위를 스캔하지 말고 쿼리하라
readingTs가 ISO-8601 문자열이므로, 시간순으로 정렬되는 것과 똑같이 사전식으로
정렬됩니다. 그래서 시간 범위 읽기는 필터가 아니라 키 조건 범위입니다:
Query
deviceId = "DEV#a1b2"
readingTs BETWEEN "2026-06-23T08:00:00Z" AND "2026-06-23T08:10:00Z"
그것은 KeyConditionExpression입니다 — DynamoDB가 데이터를 반환하기 전에 읽기를
좁히므로, 범위 내 아이템에 대해서만 비용을 냅니다. FilterExpression은 읽기 후
실행되며 스캔한 모든 것에 대해 비용을 청구합니다. 그것이 작은 규모의
Scan 지뢰입니다.
표현식 자체는 자리표시자와 타입이 지정된 값이 들어가 손으로 쓰기 까다롭습니다.
DynamoDB Expression Builder로 시각적으로 만들고
정확한 KeyConditionExpression을 SDK 호출에 복사하세요.
정렬 키를 의도적으로 설계하라
정렬 키는 공짜 메타데이터가 아닙니다 — 범위 읽기를 위한 유일한 지렛대이므로, 쿼리에 맞춰 형성하세요.
- 정렬 가능한 타임스탬프를 쓰세요. ISO-8601 문자열이나 0으로 채운 epoch 숫자는 올바르게 정렬됩니다. 가공되지 않은 현지화된 날짜는 그렇지 않습니다.
- 일대다 오버로딩을 위해 접두사를 붙이세요.
READING#2026-06-23T08:00:00Z같은 정렬 키는 하나의 파티션 아래 엔티티 유형을 섞고begins_with로 잘라내게 합니다. 그것이 단일 테이블 설계로 들어가는 이음매입니다. - 카디널리티가 높은 차원을 파티션 키에 두세요. 센서 id는 값이 수천 개라 쓰기를 고르게
분산합니다. 카디널리티가 낮은 파티션 키(예:
region)는 핫 파티션을 만듭니다.
복합 키가 당신을 물 때
그것은 편의가 아니라 약속입니다. 함정: 파티션 키를 고르고, 출시하고, 그 다음 다른 그룹화가 필요한 액세스 패턴을 발견하는 것 — "전체 무리에서 30°C를 넘는 모든 측정값".
베이스 테이블은 그것에 답할 수 없습니다. 파티션 키가 고정되어 있으니까요. 선택지는 다른 키를 가진 글로벌 보조 인덱스이거나 재구조화입니다.
키 스키마를 확정하기 전에 읽기를 열거하세요. 기본 키를 바꾸는 것은 ALTER TABLE이
아니라 테이블 마이그레이션입니다.
다음 단계
복합 키는 아이템 컬렉션, 일대다 관계, 그리고 대부분의 유용한 인덱스 설계 아래에 깔린 기반입니다 — 어디로 이어지는지 보려면 단일 테이블 설계와 GSI vs LSI를 다음으로 읽으세요.
DynamoDB Expression Builder에서
KeyConditionExpression을 스케치한 다음, DynoTable을 사용해 실제
파티션을 둘러보고 정렬 순서가 자신의 테이블에서 맞아떨어지는 모습을 지켜보세요.