본문으로 건너뛰기
김신건의 로그

[DB] DynamoDB: PK + SK, single-table design, GSI / LSI

· 수정 · 📖 약 2분 · 559자/단어 #dynamodb #nosql #aws #key-value #document
DynamoDB, DDB, partition key, sort key, GSI, LSI, single-table design, DAX, PartiQL

정의

DynamoDB 는 AWS 의 fully managed key-value + document NoSQL. low-latency, infinite scale, schemaless. single-table design 이 트레이드마크 패턴.

핵심 키

Primary Key = Partition Key (PK)
           또는 Partition Key + Sort Key (PK + SK) ← Composite
의미
PK (Partition Key)hash → 물리 partition 결정
SK (Sort Key)같은 PK 안의 정렬 키

IMPORTANT

DynamoDB 의 모든 query 는 PK 를 반드시 지정. SK 는 range query 가능. 이 제약이 single-table design 을 강제.

Item 예시

PKSKTypeData
USER#42PROFILEusername, email
USER#42ORDER#2026-06-25#o_1ordertotal, items
USER#42ORDER#2026-06-24#o_2ordertotal, items
USER#42ADDR#homeaddresscity, street
ORDER#o_1METAorderuserId, status

한 테이블에 여러 entity type 동시 저장. 한 query 로 user 의 모든 데이터:

PK = USER#42  → 모든 row (PROFILE, ORDER, ADDR)
PK = USER#42 AND SK begins_with(ORDER#) → 주문만

Capacity Mode

모드의미
ProvisionedRCU/WCU 미리 설정
On-Demand자동 스케일, 사용량 청구
단위1 RCU1 WCU
Eventually consistent2 read/sec (4KB)-
Strongly consistent1 read/sec-
Write-1 write/sec (1KB)

Strongly vs Eventually Consistent Read

flowchart LR
    Write[Write] --> Leader[Leader replica]
    Leader -.async.-> R1[Replica 1]
    Leader -.async.-> R2[Replica 2]
    Read1[Strong read] --> Leader
    Read2[Eventual read] --> R1
    Read2 --> R2
StrongEventual
Latency약간 높음낮음
Cost (RCU)2배기본
일관성항상 최신최근 쓰기 못 봄 가능

GSI vs LSI

LSI (Local)GSI (Global)
PK같은 base table 의 PK임의 키
동시 생성create 시만언제든
일관성strong / eventualeventual 만
크기 제한10GB / PK없음
개수520
flowchart LR
    Base["Base table (PK, SK)"]
    Base --> LSI1["LSI (PK, new_SK)"]
    Base --> GSI1["GSI (different_PK, different_SK)"]

Single-Table Design

flowchart TB
    Q[모든 access pattern 정의]
    Q --> Choose[PK + SK 선택]
    Choose --> One[ONE table 에 모든 entity]
    One --> Why[*Join 없이* 한 query 로 끝]

IMPORTANT

RDB 사고 (테이블 = entity)완전 다른 패러다임. access pattern 을 먼저 정의, 그에 맞춰 PK/SK 디자인. 잘못 설계하면 전체 마이그레이션.

Query vs Scan

# Query (효율적, PK 필수)
QUERY PK = "USER#42" AND SK begins_with "ORDER#"

# Scan (전체 테이블 순회, 비효율)
SCAN FilterExpression: "status = paid"

WARNING

Scan 은 거의 항상 안티패턴. 모든 partition 순회 → 비용 폭발. Scan 이 자주 필요하면 디자인 결함.

DAX (DynamoDB Accelerator)

flowchart LR
    App --> DAX["DAX Cluster<br/>(in-memory cache)"]
    DAX -->|miss| DDB[(DynamoDB)]
    DAX -.->|hit| App
  • 마이크로초 단위 latency.
  • write-through 캐시.
  • 읽기 중심 워크로드에서 효과.

Streams + Lambda

flowchart LR
    DDB[(DynamoDB Table)] -->|change stream| Streams[DDB Streams]
    Streams --> Lambda[Lambda]
    Lambda --> ES[ElasticSearch]
    Lambda --> SNS[SNS]
    Lambda --> SQS[SQS]

Change Data Capture. secondary index 가 부족할 때 Streams 로 외부 검색 인덱스 동기화.

PartiQL

-- SQL-like 쿼리
SELECT * FROM "MyTable" WHERE PK = 'USER#42' AND begins_with("SK", 'ORDER#');

익숙한 SQL 문법이지만 내부는 여전히 PK/SK 제약 적용. RDB 쿼리처럼 작성하면 Scan 폭발.

흔한 함정

WARNING

  1. Hot partition = 특정 PK 에 트래픽 집중. 분산 키 디자인 (해시 prefix).
  2. 너무 큰 item = 400KB 제한. 큰 데이터는 S3 + DDB 에 참조.
  3. Scan 의존 쿼리 = 비용 폭발. GSI 추가.
  4. eventual consistency 무시 = 방금 쓴 값이 없을 수 있음. strong read 명시 또는 재시도.

관련 위키

이 글의 용어 (4개)
[AWS] IAM: User, Role, Policy, STScloud
정의 IAM (Identity and Access Management) = AWS 의 권한 관리 전부. User, Group, Role, Policy. 객체 | 객체 | 의미 |…
[DB Internals] Redis 8 / Valkey 9: 라이센스 분기, 신 데이터 구조, 실전 운영database-internals
정의 Redis 는 in-memory key-value 데이터 구조 서버. 2009년 Salvatore Sanfilippo (antirez) 가 Lua Manuscripts 의 …
[DB] MongoDB: 문서 DB, WiredTiger, replica set, aggregationdatabase-internals
정의 MongoDB 는 BSON (binary JSON) 문서 기반 NoSQL DB. schema-less 라기보다 flexible schema. 2026 시점 Atlas (ma…
[DB] Sharding vs Partitioning: 수평 확장의 두 얼굴database-internals
정의 | | Partitioning | Sharding | |---|---|---| | 범위 | 한 DB 안 | 여러 DB 노드 | | 목적 | 큰 테이블 관리 | 수평 확장 (…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기