NoSQL 데이터 모델링을 쿼리 중심으로 설계하는 방법

NoSQL 데이터 모델링에서 도메인 분석, 쿼리 결과 설계, 파티션 전략, 제품 검증과 운영 최적화까지 정리합니다.

2026-08-14 · 최초 발행 2025-10-14

RDB 설계 원칙만으로는 해결되지 않는 워크로드

OLTP, 실시간 분석, 대규모 사용자 트래픽 환경에서는 RDB 설계 원칙만으로 성능과 확장성의 한계가 생길 수 있다. NoSQL 데이터 모델링은 쿼리 우선 설계와 패턴 기반 모델링을 통해 워크로드에 맞는 구조를 만드는 일이다.

도메인을 파악하고, 필요한 쿼리 결과를 정의한 뒤, 물리 모델과 최적화 기능을 결정한다. 이어서 제품을 선택해 테스트하고, 운영 환경의 용량과 하드웨어 계획까지 연결한다.

쿼리가 스키마를 이끄는 모델링 방식

NoSQL 데이터 모델링은 비정규화와 중복 저장을 허용하면서 특정 워크로드의 지연시간과 처리량을 높이기 위한 데이터 구조 설계 활동이다. 핵심은 쿼리가 스키마를 결정한다는 원칙이다.

접근 패턴에 맞춰 파티션과 키를 설계하고, 일관성 모델 및 보상 트랜잭션도 함께 고려한다. 논리 설계에서는 쿼리 결과 모델을 만들고, 물리 설계에서는 테이블 또는 컬렉션, 파티션과 인덱스, TTL과 스토리지 엔진을 정한다. 이후 성능 검증과 하드웨어 적합성 평가까지 범위에 포함된다.

도메인 요구를 수집할 때는 이벤트, 엔터티, 관계, 수명주기와 함께 데이터 식별자 및 카디널리티를 분석한다. 규범화보다 어떤 접근 패턴을 먼저 지원해야 하는지가 우선이다. 화면이나 API 단위에서는 단일 요청으로 단일 응답을 반환할 수 있도록 결과 스키마를 고정하며, 조인을 피하기 위한 중첩 문서와 중복 저장을 허용한다.

물리 모델에는 단일 테이블 설계(STD), 타임시리즈, 인버티드 인덱스, 컨텍스추얼 세컨더리 인덱스, CQRS, 이벤트 소싱 같은 패턴을 적용할 수 있다. 이때 파티션 키, 클러스터링 키, 버전과 TTL 전략은 분리해서 결정할 대상이 아니다.

도메인에서 운영 모델까지 이어지는 설계 흐름

도메인 모델에서 데이터 경계를 잡는다

비즈니스 프로세스, 주요 엔터티와 이벤트, SLO(지연/가용성), 데이터 보존 및 규제 요건을 입력으로 삼는다. 유즈케이스에서 이벤트 스토밍을 거쳐 엔터티(집합체)를 도출하고, 자연키 또는 대체키로 식별자를 설계한다. 카디널리티와 데이터 볼륨도 함께 추정한다.

이 단계의 산출물은 도메인 개념모델, 우선순위 접근 패턴 목록, 작성→변경→아카이브→삭제로 이어지는 데이터 수명주기다. 강한 일관성이 필요한 경계를 정의하고 GDPR/PII 처리 경계도 확정한다.

API가 요구하는 결과 형태를 먼저 정한다

화면과 API 스펙, SLA, 캐시 전략을 바탕으로 요청마다 단일 쿼리로 돌려줄 결과 스키마를 설계한다. 조인을 제거하기 위해 중복 및 중첩 구조를 허용하고, 정렬·페이징·필터 기준을 확정한다.

결과 프로젝션 문서 또는 레코드 설계서와 필수·옵셔널 인덱스 후보, TTL 및 버전의 필요성이 이 단계에서 나온다. N+1을 피하고 1RTT 조회 원칙을 만족하는지 확인한다.

주문 상세 API라면 입력 키는 userId, orderId이고, 결과에는 orderSummary, items[], payment, shipment, statusHistory[]가 포함될 수 있다.

파티션과 인덱스로 물리 모델을 구성한다

쿼리 결과 설계서와 트래픽 패턴(R/W 비율, 시간대 집중), 데이터 분포를 기준으로 파티션 키와 클러스터링 키를 설계한다. 파티션 키는 균등성에, 클러스터링 키는 정렬과 범위 조회에 직접 영향을 준다.

컬렉션·테이블·CF 형태의 물리 스키마와 파티셔닝·샤딩 전략, 인덱스·TTL·컴팩션 정책을 결정한다. 단일 테이블 설계(STD), 타임시리즈, 세컨더리 인덱스, 인버티드 인덱스는 접근 패턴에 따라 적용한다. 핫파티션과 스키유 방지, 대용량 페이지네이션의 안정성이 주요 점검 대상이다.

간단한 모델의 예시는 다음과 같다.

  • MongoDB(6+)
    • 컬렉션: orders
    • 샤드 키: { userId: hashed }
    • 인덱스: { userId: 1, createdAt: -1 }, partial index on status
  • Cassandra(4+)
    • 테이블: orders_by_user(user_id PARTITION KEY, created_at CLUSTERING, order_id, summary, …) WITH CLUSTERING ORDER BY (created_at DESC)

병목을 줄일 기능을 우선순위로 관리한다

예상 병목 지표, 운영 제약, 보안 요구를 바탕으로 캐시 전략(Redis/SDK 캐시), CQRS 분리, 이벤트 소싱과 Change Data Capture, 멱등키와 보상 트랜잭션, 데이터 축약 스냅샷을 검토한다.

성능·일관성·운영 편의를 높일 기능 목록과 우선순위를 정하고 P95, P99, TPS, Hot key ratio 같은 측정 지표를 정의한다. 복잡도가 늘어나는 만큼의 효과가 있는지, 운영 자동화가 가능한지도 함께 판단한다.

제품은 워크로드로 검증한다

후보 제품군을 키-값, 도큐먼트, 컬럼, 그래프 유형으로 한정하고 클라우드·온프렘 제약, 라이선스와 비용을 반영한다. 트랜잭션, TTL, 이벤트, 인덱스, 쿼리 기능을 매핑하고 CA/CP/AP 일관성 모델을 평가한 뒤 워크로드를 재현하는 벤치를 수행한다.

성능·확장성·일관성·안정성·운영 편의 비교 결과와 TCO 추정이 산출물이다. 최신 정보 확인, 멀티 AZ/리전 DR 전략의 가용성도 확인해야 한다.

벤치에서는 다음 지표를 확인한다.

  • 읽기 지연 P95/P99, 쓰기 지연 P95/P99
  • 파티션 불균형률, GC/Compaction 영향
  • 재시도율/타임아웃율, 장애 시 RTO/RPO

확정한 엔진에 맞춰 운영 설계를 마무리한다

선정한 엔진의 문서 크기와 파티션 제한, 관찰된 병목을 입력으로 파티션을 다시 설계하고 인덱스를 튜닝한다. TTL, 압축, 컴팩션, 메모리 파라미터와 동시성·일관성 옵션도 조정 대상이다.

최종 산출물은 확정 스키마, 운영 파라미터, 용량·HW/인스턴스 타입, 오토스케일·백업·모니터링 계획이다. 카나리 배포, 샤드 증설, 데이터 마이그레이션의 롤백 절차를 포함해야 한다.

용량 산정은 다음 개념식으로 정리할 수 있다.

  • 저장량 ≈ 일평균 문서수 × 문서크기 × 보존일 × 복제계수 × 압축역수
  • IOPS ≈ 초당 요청 × (읽기/쓰기 비율) × 평균 재시도 계수

모델 검증과 재설계가 반복되는 구조

도큐먼트/컬럼/키값/그래프통과미달이상 지표요구사항/도메인 입력도메인 모델 파악엔터티·이벤트·식별자Query Result Design단일 요청-단일 응답 스키마패턴 기반 물리 설계파티션/클러스터링/인덱스최적화 기능 리스팅캐시/CQRS/CDCNoSQL 후보 선정벤치마크/적합성 테스트최종 모델 확정HW/용량 설계·운영계획프로덕션/모니터링

벤치 결과가 기준에 미달하면 파티션, 인덱스, 일관성 레벨을 다시 설계한 뒤 검증한다. 핫키가 발생하면 키 해싱 또는 버킷팅, TTL 분산, 캐시 레이어 추가를 검토한다. 트랜잭션이 필요할 때는 로컬 트랜잭션과 보상 트랜잭션을 설계하고 멱등성을 보장한다.

주문 조회 패턴으로 보는 모델 선택

전자상거래 주문과 주문 목록에서는 주문 상세를 (userId, orderId)로 조회하며 1RTT를 요구할 수 있다. 주문 목록은 userId를 기준으로 createdAt desc 정렬과 페이지네이션이 필요하다.

도큐먼트 모델에서는 MongoDB의 orders 컬렉션을 사용자 단위로 샤딩하고 items를 중첩할 수 있다. 상태 변경은 append-only statusHistory로 관리한다. 컬럼 모델에서는 Cassandra의 orders_by_user 테이블을 (user_id, created_at DESC) 기반 목록 조회에 사용하고, 상세 조회는 별도 orders_by_id 테이블에 둔다.

읽기 캐시에는 Redis setex(order:{id}) TTL=5m를 적용할 수 있다. CDC를 통해 Elasticsearch 검색 색인에 비동기로 반영하면 목록 필터를 고도화할 수 있고, 결제·주문 생성 API에는 idempotencyKey를 적용한다.

MongoDB 6+ (Node.js)

// 전제: Node.js 18+, mongodb 5.x 드라이버
// 단일 RT 조회: 상세
await db
  .collection("orders")
  .findOne({ userId, orderId }, { projection: { _id: 0 } });

// 목록 조회: 페이지네이션
await db
  .collection("orders")
  .find({ userId, createdAt: { $lt: cursor } })
  .sort({ createdAt: -1 })
  .limit(50)
  .hint({ userId: 1, createdAt: -1 })
  .toArray();

Cassandra 4+ (CQL)

-- 전제: RF=3, LWT 최소화
CREATE TABLE orders_by_user (
  user_id text,
  created_at timestamp,
  order_id text,
  summary text,
  PRIMARY KEY ((user_id), created_at, order_id)
) WITH CLUSTERING ORDER BY (created_at DESC);

워크로드에 따라 달라지는 제품 유형의 특성

타입 성능(지연/처리량) 확장성(샤딩/리밸런스) 일관성 모델 안정성(장애/복구) 운영 편의(스키마/인덱스)
키-값 매우 우수함, 단순 키 조회 최적화 수평 확장 용이, 핫키 리스크 최종 일관성 중심(선택적 강일) 단순 구조로 고가용성 용이 스키마 자유, 쿼리 유연성 낮음
도큐먼트 읽기/쓰기 균형, 중첩 문서 강점 샤딩 정책 중요, 크기 제한 고려 튜너블(강/약), 트랜잭션 일부 지원 컬렉션 단위 복제/샤딩 안정적 스키마 유연, 인덱스 다양
컬럼 패밀리 대량 쓰기·범위 읽기 강함 파티션 설계 품질에 좌우 일관성 튜너블, LWT 비용 큼 컴팩션/GC 관리 중요 스키마 필요, 설계 난이도 높음
그래프 관계 탐색 지연 최적화 분산 시 난이도 높음 제품별 상이 파티션 전략 복잡 질의 표현력 높으나 운영 난이도 높음

쿼리 우선 설계와 패턴 기반 모델링을 체계적으로 적용하면 P95 지연 3070% 감소, P99 일탈 감소, 읽기 TPS 25배 향상을 기대할 수 있다. 샤드 추가 시 선형 확장성 7090% 달성과 핫파티션률 < 3% 유지를 목표로 하며, 인시던트 MTTR은 2040% 단축되고 운영 비용(TCO)은 15~35% 절감될 수 있다. 데이터 일관성 이슈와 배포·스키마 변경 리스크도 줄어든다.

처음에는 단순성과 1RTT 원칙을 유지하고, 관찰된 병목에 한해 점진적으로 최적화하는 편이 적합하다. 선정, 테스트, 최적화, 운영은 분리된 단계가 아니라 벤치 지표와 핫파티션 관리를 중심으로 계속 순환하는 과정이다.

NoSQL데이터 모델링파티셔닝쿼리 우선 설계CQRS