Next.js 시니어 데이터베이스 기술면접

Next.js 시니어 (7년+) 데이터베이스 10문항 조회수 28 · 2026-08-27 (목) 07:42:35
1 파티셔닝 전략
Hard

Q. Next.js 기반 로그 분석 플랫폼에서 events 테이블이 월 10억 건 이상 증가하며, 특정 기간의 데이터 조회 시 응답 시간이 30초를 초과합니다. 테이블 파티셔닝(Range, Hash, List)을 도입할 때 각 전략의 특징과 선택 기준, 그리고 파티션 프루닝 최적화 방법을 설명해주세요. 또한 기존 데이터를 파티션 테이블로 마이그레이션하는 무중단 전환 전략도 포함해주세요.

시계열 데이터의 특성과 쿼리 패턴(날짜 범위 조회)을 고려하여 파티션 키를 선택하세요.

A. 모범답안

시계열 로그 데이터는 Range 파티셔닝이 가장 적합하며, created_at 컬럼을 기준으로 월별 또는 주별 파티션을 생성합니다. 파티션 프루닝을 위해 WHERE 절에 파티션 키를 반드시 포함하고, 쿼리 플랜에서 실제로 스캔되는 파티션 수를 확인해야 합니다. 무중단 마이그레이션은 새 파티션 테이블을 생성하고, 트리거 또는 CDC를 통해 실시간 데이터를 이중 쓰기하며, 과거 데이터는 배치로 이관한 후 애플리케이션 라우팅을 전환합니다. 오래된 파티션은 DETACH/DROP으로 빠르게 삭제할 수 있어 데이터 보관 정책 구현이 용이합니다. Next.js Server Actions에서는 파티션 키를 쿼리 조건에 명시적으로 포함하여 성능을 보장해야 합니다.

핵심 포인트
  • • Range 파티셔닝을 통한 시계열 데이터 분할
  • • 파티션 프루닝을 위한 쿼리 조건 설계
  • • 무중단 마이그레이션을 위한 이중 쓰기 전략
  • • 파티션 단위 데이터 삭제로 보관 정책 구현
답변에 넣으면 좋은 키워드
Range Partitioning Partition Pruning DETACH CDC 이중 쓰기 시계열 데이터
실무에서는

대용량 로그, 이벤트 추적, 시계열 메트릭 저장 시스템에서 파티셔닝으로 쿼리 성능과 유지보수성을 개선합니다.

Follow-up 질문

파티션 테이블에서 글로벌 인덱스와 로컬 인덱스의 차이, 그리고 각각의 성능 특성을 설명해주세요.

2 데드락 분석
Hard

Q. Next.js 기반 재고 관리 시스템에서 주문 생성 시 여러 테이블(orders, order_items, inventory)을 업데이트하는 과정에서 데드락이 빈번하게 발생합니다. 데드락의 발생 원인과 탐지 방법, 그리고 트랜잭션 설계 개선을 통한 데드락 방지 전략을 설명해주세요. PostgreSQL의 pg_locks와 pg_stat_activity를 활용한 디버깅 방법도 포함해주세요.

여러 자원에 대한 락 획득 순서가 트랜잭션마다 다를 때 데드락이 발생합니다.

A. 모범답안

데드락은 두 개 이상의 트랜잭션이 서로 다른 순서로 자원을 잠그려 할 때 발생하며, 특히 inventory 업데이트 순서가 일관되지 않으면 문제가 됩니다. 해결 방법은 모든 트랜잭션에서 동일한 순서로 락을 획득하도록 강제하는 것으로, inventory_id를 정렬한 후 순차적으로 FOR UPDATE를 실행합니다. pg_locks 뷰로 현재 락 상태를 확인하고, pg_stat_activity로 블로킹 관계를 추적하며, log_lock_waits 설정으로 데드락 로그를 수집합니다. 트랜잭션 범위를 최소화하고, 배치 업데이트 시 청크 단위로 분할하여 락 경합을 줄이는 것도 중요합니다. Next.js Server Actions에서는 트랜잭션 내 비즈니스 로직 실행 시간을 줄이고, 외부 API 호출은 트랜잭션 외부로 분리해야 합니다.

핵심 포인트
  • • 락 획득 순서 일관성 유지로 데드락 방지
  • • pg_locks와 pg_stat_activity를 통한 락 모니터링
  • • 트랜잭션 범위 최소화 및 청크 단위 처리
  • • 비즈니스 로직과 트랜잭션 분리
답변에 넣으면 좋은 키워드
데드락 FOR UPDATE 락 순서 pg_locks 트랜잭션 범위 청크 처리
실무에서는

재고 관리, 결제 처리, 좌석 예약 등 여러 자원을 동시에 업데이트하는 트랜잭션에서 데드락을 방지해야 합니다.

Follow-up 질문

SERIALIZABLE 격리 수준에서 발생하는 직렬화 실패(Serialization Failure)와 데드락의 차이를 설명하고, 각각의 재시도 전략을 제시해주세요.

3 샤딩 아키텍처
Hard

Q. Next.js 기반 글로벌 메시징 플랫폼에서 단일 데이터베이스의 용량 한계에 도달하여 수평 샤딩을 도입하려고 합니다. 샤드 키 선택 기준(user_id, tenant_id 등), 샤드 라우팅 로직 구현, 크로스 샤드 쿼리 처리 방법, 그리고 샤드 리밸런싱 전략을 설명해주세요. 특히 애플리케이션 레벨 샤딩과 데이터베이스 레벨 샤딩의 트레이드오프를 포함해주세요.

샤드 키는 쿼리 패턴과 데이터 분포를 고려하여 선택하며, 한 번 선택하면 변경이 어렵습니다.

A. 모범답안

메시징 플랫폼에서는 user_id를 샤드 키로 선택하여 특정 사용자의 모든 메시지가 같은 샤드에 저장되도록 하면 대부분의 쿼리가 단일 샤드에서 처리됩니다. 애플리케이션 레벨 샤딩은 샤드 라우팅 로직을 직접 구현해야 하지만 유연성이 높고, Vitess나 Citus 같은 데이터베이스 레벨 솔루션은 투명하지만 종속성이 생깁니다. 크로스 샤드 쿼리는 애플리케이션에서 병렬로 실행 후 머지하거나, 글로벌 검색은 Elasticsearch 같은 별도 인덱스를 활용합니다. 샤드 리밸런싱은 Consistent Hashing을 사용하여 최소한의 데이터만 이동하도록 설계하며, 가상 노드 개념으로 부하를 균등 분산합니다. Next.js에서는 미들웨어나 Server Actions에서 샤드 키를 추출하여 적절한 DB 연결을 선택하는 라우팅 레이어를 구현합니다.

핵심 포인트
  • • 쿼리 패턴 기반 샤드 키 선택
  • • 애플리케이션 레벨 vs 데이터베이스 레벨 샤딩 비교
  • • Consistent Hashing을 통한 리밸런싱
  • • 크로스 샤드 쿼리를 위한 별도 인덱스 활용
답변에 넣으면 좋은 키워드
샤딩 샤드 키 Consistent Hashing 크로스 샤드 쿼리 가상 노드 라우팅 레이어
실무에서는

대규모 SaaS, 메시징, 소셜 플랫폼에서 수평 확장을 위해 샤딩을 도입하며, 초기 설계가 매우 중요합니다.

Follow-up 질문

샤딩된 환경에서 분산 트랜잭션(2PC, Saga 패턴)이 필요한 경우와 이를 회피하기 위한 설계 원칙을 설명해주세요.

4 쿼리 실행 계획
Medium

Q. Next.js 대시보드에서 복잡한 집계 쿼리(JOIN 5개, GROUP BY, HAVING)의 응답 시간이 15초를 초과합니다. EXPLAIN ANALYZE를 활용하여 쿼리 실행 계획을 분석하고, 병목 지점을 식별하는 방법을 설명해주세요. Seq Scan, Index Scan, Nested Loop, Hash Join, Merge Join의 차이와 각각이 선택되는 조건, 그리고 쿼리 힌트나 통계 업데이트를 통한 최적화 방법을 포함해주세요.

실행 계획에서 각 노드의 cost, rows, actual time을 비교하여 예상과 실제가 크게 다른 부분을 찾으세요.

A. 모범답안

EXPLAIN ANALYZE는 실제 실행 시간과 예상 비용을 함께 보여주며, Seq Scan이 나타나면 인덱스 누락을, Hash Join의 메모리 부족은 work_mem 조정 필요성을 의미합니다. Nested Loop는 작은 결과셋 조인에, Hash Join은 큰 테이블 조인에, Merge Join은 정렬된 데이터 조인에 효율적입니다. rows 예상치가 실제와 크게 다르면 ANALYZE 명령으로 통계를 업데이트하거나, 히스토그램 통계를 수집해야 합니다. 필터 조건의 selectivity가 낮으면 부분 인덱스나 복합 인덱스로 개선하고, CTE보다 서브쿼리가 최적화에 유리한 경우도 있습니다. Next.js에서는 Server Components에서 실행되는 복잡한 쿼리를 모니터링하고, 슬로우 쿼리 로그를 수집하여 지속적으로 최적화해야 합니다.

핵심 포인트
  • • EXPLAIN ANALYZE로 예상과 실제 실행 차이 분석
  • • 조인 알고리즘별 특성과 선택 조건 이해
  • • 통계 업데이트와 인덱스 개선을 통한 최적화
  • • 슬로우 쿼리 모니터링 및 지속적 개선
답변에 넣으면 좋은 키워드
EXPLAIN ANALYZE Seq Scan Hash Join Nested Loop work_mem 통계 업데이트
실무에서는

복잡한 리포트, 대시보드, 분석 쿼리의 성능 문제를 진단하고 최적화할 때 실행 계획 분석이 필수입니다.

Follow-up 질문

PostgreSQL의 쿼리 플래너가 잘못된 실행 계획을 선택했을 때, 쿼리 힌트 없이 통계 정보나 설정 조정만으로 개선하는 방법을 설명해주세요.

5 정규화와 역정규화
Medium

Q. Next.js 기반 이커머스 플랫폼에서 주문 내역 조회 시 상품 정보, 가격, 할인율 등을 표시해야 합니다. 정규화된 스키마에서는 여러 테이블을 조인해야 하지만, 역정규화하면 데이터 일관성 문제가 발생할 수 있습니다. 정규화와 역정규화의 트레이드오프를 분석하고, 주문 스냅샷 패턴, Materialized View, JSONB 컬럼 활용 등 하이브리드 접근법을 제시해주세요.

주문 시점의 상품 정보는 이후 상품 정보가 변경되어도 유지되어야 하는 불변 데이터입니다.

A. 모범답안

주문 데이터는 스냅샷 패턴을 적용하여 주문 시점의 상품명, 가격, 옵션을 order_items 테이블에 역정규화하여 저장하는 것이 적합합니다. 이는 과거 주문 내역이 현재 상품 정보 변경에 영향받지 않아야 하는 비즈니스 요구사항을 반영한 것입니다. 자주 조회되지만 업데이트가 드문 집계 데이터는 Materialized View로 구현하고, REFRESH CONCURRENTLY로 주기적 갱신합니다. JSONB 컬럼은 유연한 속성 저장에 유용하며, GIN 인덱스로 검색 성능을 확보할 수 있습니다. 정규화는 쓰기 성능과 일관성에, 역정규화는 읽기 성능에 유리하므로, 읽기/쓰기 비율과 일관성 요구사항에 따라 선택합니다. Next.js에서는 Server Components에서 역정규화된 데이터를 직접 조회하여 조인 오버헤드를 줄입니다.

핵심 포인트
  • • 스냅샷 패턴으로 시점 데이터 보존
  • • Materialized View를 통한 집계 데이터 캐싱
  • • JSONB와 GIN 인덱스로 유연한 스키마 구현
  • • 읽기/쓰기 패턴에 따른 전략 선택
답변에 넣으면 좋은 키워드
스냅샷 패턴 역정규화 Materialized View JSONB GIN 인덱스 읽기 최적화
실무에서는

주문, 청구서, 계약서 등 시점 데이터를 보존해야 하는 도메인에서 스냅샷 패턴을 활용합니다.

Follow-up 질문

Materialized View와 일반 캐시(Redis) 중 어떤 것을 선택할지 판단하는 기준과, 각각의 갱신 전략을 비교해주세요.

6 JSONB 활용
Medium

Q. Next.js 기반 CMS에서 다양한 콘텐츠 타입(블로그, 동영상, 이벤트)이 각각 고유한 메타데이터를 가지고 있습니다. EAV 모델, 테이블 상속, JSONB 컬럼 중 어떤 방식을 선택할지 비교하고, JSONB를 선택했을 때 인덱싱 전략(GIN, Expression Index), 쿼리 성능, 스키마 검증 방법을 설명해주세요.

각 콘텐츠 타입의 속성이 자주 변경되고, 타입 간 공통 쿼리가 필요한지 고려하세요.

A. 모범답안

JSONB는 유연한 스키마가 필요하고 타입별 속성이 자주 변경되는 경우 적합하며, EAV는 쿼리가 복잡해지고 성능이 떨어지므로 피해야 합니다. JSONB 컬럼에는 GIN 인덱스를 생성하여 @>, ? 연산자로 효율적인 검색이 가능하며, 특정 경로의 값에는 Expression Index를 생성합니다. 예를 들어 (metadata->>'category')에 인덱스를 생성하면 카테고리 필터링이 빨라집니다. 스키마 검증은 애플리케이션 레벨에서 Zod나 JSON Schema로 수행하거나, PostgreSQL의 CHECK 제약조건으로 기본 검증을 추가할 수 있습니다. JSONB는 압축 저장되어 공간 효율적이지만, 전체 컬럼 업데이트 시 오버헤드가 있으므로 자주 변경되는 필드는 별도 컬럼으로 분리합니다. Next.js에서는 타입 안전성을 위해 Prisma의 Json 타입과 Zod 스키마를 조합하여 사용합니다.

핵심 포인트
  • • JSONB의 유연성과 GIN 인덱스 성능
  • • Expression Index로 특정 경로 최적화
  • • 애플리케이션 레벨 스키마 검증
  • • 자주 변경되는 필드는 별도 컬럼 분리
답변에 넣으면 좋은 키워드
JSONB GIN 인덱스 Expression Index JSON Schema 유연한 스키마 Zod
실무에서는

CMS, 설정 관리, 이벤트 로그, 사용자 프로필 등 유연한 속성이 필요한 도메인에서 JSONB를 활용합니다.

Follow-up 질문

JSONB 컬럼의 깊이가 3단계 이상 중첩될 때 발생하는 성능 문제와, 이를 해결하기 위한 스키마 재설계 방법을 설명해주세요.

7 배치 처리 최적화
Hard

Q. Next.js 백오피스에서 100만 건의 사용자 포인트를 일괄 업데이트하는 배치 작업이 있습니다. 단순 루프로 처리 시 3시간이 걸리며, 데이터베이스 부하도 높습니다. 벌크 업데이트 최적화 방법(COPY, INSERT ON CONFLICT, 임시 테이블 활용), 트랜잭션 분할 전략, 그리고 배치 작업 중 서비스 영향 최소화 방안을 설명해주세요.

대량 데이터는 한 번에 처리하지 말고, 청크 단위로 나누고 임시 테이블을 활용하세요.

A. 모범답안

벌크 업데이트는 CSV 파일을 COPY 명령으로 임시 테이블에 적재한 후, UPDATE FROM 또는 INSERT ON CONFLICT로 병합하는 방식이 가장 빠릅니다. 트랜잭션은 10,000건 단위로 청크를 나누어 커밋하고, 실패 시 해당 청크만 재시도하여 롤백 오버헤드를 줄입니다. 배치 작업 중 서비스 영향을 최소화하려면 statement_timeout을 설정하고, 피크 시간을 피해 실행하며, 인덱스는 작업 후 재생성합니다. UNLOGGED 테이블을 임시 테이블로 사용하면 WAL 쓰기를 생략하여 성능이 향상됩니다. 진행률 추적을 위해 중간 상태를 별도 테이블에 기록하고, 멱등성을 보장하여 재실행 가능하도록 설계합니다. Next.js에서는 Server Actions보다 별도 워커 프로세스나 큐 시스템에서 배치를 실행하는 것이 적합합니다.

핵심 포인트
  • • COPY와 임시 테이블을 활용한 벌크 처리
  • • 청크 단위 트랜잭션 분할
  • • UNLOGGED 테이블로 성능 향상
  • • 멱등성과 진행률 추적 구현
답변에 넣으면 좋은 키워드
COPY INSERT ON CONFLICT 청크 처리 UNLOGGED 벌크 업데이트 statement_timeout
실무에서는

정산, 포인트 일괄 지급, 데이터 마이그레이션, 통계 집계 등 대량 데이터 처리 시 배치 최적화가 필수입니다.

Follow-up 질문

배치 작업 중 발생한 에러를 추적하고, 실패한 레코드만 선택적으로 재처리하는 아키텍처를 설계해주세요.

8 시계열 데이터 모델링
Hard

Q. Next.js 기반 IoT 모니터링 플랫폼에서 수천 개의 센서로부터 초당 수만 건의 메트릭 데이터를 수집하고, 시간대별 집계와 이상 탐지를 수행해야 합니다. TimescaleDB, InfluxDB 같은 시계열 DB와 PostgreSQL의 비교, Hypertable과 Continuous Aggregate 활용, 다운샘플링 전략, 그리고 데이터 보관 정책을 설명해주세요.

시계열 데이터는 쓰기가 많고 오래된 데이터는 정밀도를 낮춰 저장할 수 있습니다.

A. 모범답안

TimescaleDB는 PostgreSQL 기반으로 SQL 호환성과 시계열 최적화를 모두 제공하며, Hypertable로 자동 파티셔닝하고 Continuous Aggregate로 실시간 집계 뷰를 유지합니다. 원본 데이터는 1분 단위로 저장하고, 1시간 후에는 5분 평균으로, 1개월 후에는 1시간 평균으로 다운샘플링하여 저장 공간을 절약합니다. Retention Policy로 오래된 청크를 자동 삭제하고, Compression으로 과거 데이터를 압축하여 저장 비용을 90% 이상 줄입니다. 이상 탐지는 Continuous Aggregate의 통계 데이터를 기반으로 수행하며, 실시간 알림은 별도 스트림 처리 레이어에서 담당합니다. Next.js에서는 읽기 쿼리에 적절한 집계 레벨을 선택하고, Server Components에서 시간 범위를 명시하여 파티션 프루닝을 활용합니다.

핵심 포인트
  • • TimescaleDB의 Hypertable과 Continuous Aggregate
  • • 다운샘플링으로 저장 공간 최적화
  • • Retention Policy와 Compression 활용
  • • 집계 레벨별 쿼리 전략
답변에 넣으면 좋은 키워드
TimescaleDB Hypertable Continuous Aggregate 다운샘플링 Retention Policy 시계열 데이터
실무에서는

IoT 모니터링, 애플리케이션 메트릭, 주식 시세, 센서 데이터 등 시계열 데이터 저장과 분석에 특화된 DB를 활용합니다.

Follow-up 질문

시계열 데이터베이스에서 늦게 도착한 데이터(Late Arriving Data)를 처리하는 방법과, 집계 결과의 정확성을 보장하는 전략을 설명해주세요.

9 인덱스 블로트
Medium

Q. Next.js 애플리케이션의 PostgreSQL 데이터베이스에서 쿼리 성능이 점진적으로 저하되고 있으며, 인덱스 크기가 테이블 크기의 3배를 초과했습니다. 인덱스 블로트의 원인과 탐지 방법, VACUUM과 REINDEX의 차이, 그리고 무중단으로 인덱스를 재구성하는 방법을 설명해주세요.

UPDATE와 DELETE가 많으면 dead tuple이 쌓이고, 인덱스도 함께 비대해집니다.

A. 모범답안

인덱스 블로트는 UPDATE/DELETE로 인한 dead tuple이 누적되어 발생하며, pg_stat_user_tables의 n_dead_tup과 pgstattuple 확장으로 블로트 비율을 측정합니다. VACUUM은 dead tuple을 정리하지만 공간을 OS에 반환하지 않고, VACUUM FULL은 테이블을 재작성하지만 배타 락이 필요합니다. REINDEX는 인덱스를 재구성하여 블로트를 제거하며, REINDEX CONCURRENTLY는 서비스 중단 없이 실행되지만 2배의 디스크 공간이 필요합니다. autovacuum 설정을 튜닝하여(autovacuum_vacuum_scale_factor 낮춤) 더 자주 실행되도록 하고, HOT(Heap-Only Tuple) 업데이트가 가능하도록 fillfactor를 조정합니다. 정기적인 모니터링으로 블로트가 30%를 초과하면 재구성을 계획하고, 피크 시간을 피해 실행합니다.

핵심 포인트
  • • pgstattuple로 블로트 비율 측정
  • • REINDEX CONCURRENTLY로 무중단 재구성
  • • autovacuum 튜닝으로 예방
  • • HOT 업데이트와 fillfactor 조정
답변에 넣으면 좋은 키워드
인덱스 블로트 VACUUM REINDEX CONCURRENTLY pgstattuple autovacuum HOT 업데이트
실무에서는

오래 운영된 서비스에서 인덱스 블로트로 인한 성능 저하가 발생하며, 정기적인 유지보수가 필요합니다.

Follow-up 질문

B-tree 인덱스에서 블로트가 발생하는 내부 메커니즘과, 특정 워크로드 패턴에서 블로트가 심해지는 이유를 설명해주세요.

10 멀티 테넌시 설계
Hard

Q. Next.js 기반 B2B SaaS에서 수천 개의 고객사(테넌트)가 동일한 애플리케이션을 사용합니다. 멀티 테넌시 데이터 격리 전략으로 스키마 분리, 테이블 분리, Row-level 분리의 장단점을 비교하고, PostgreSQL의 Row-Level Security(RLS)를 활용한 구현 방법과 성능 영향을 설명해주세요. 특히 대형 고객사와 소형 고객사를 차별화하는 하이브리드 접근법도 포함해주세요.

테넌트별 데이터 크기와 격리 요구사항이 다르면, 단일 전략보다 하이브리드가 적합합니다.

A. 모범답안

Row-level 분리는 구현이 간단하고 운영 비용이 낮지만, 한 테넌트의 쿼리가 다른 테넌트에 영향을 줄 수 있고, 스키마 분리는 완전한 격리를 제공하지만 관리 복잡도가 높습니다. PostgreSQL의 RLS는 tenant_id 기반 정책으로 자동 필터링하여 애플리케이션 코드를 단순화하지만, 모든 쿼리에 필터가 추가되어 성능 영향이 있으므로 tenant_id 인덱스가 필수입니다. 대형 고객사는 별도 스키마나 데이터베이스로 분리하여 성능과 보안을 보장하고, 소형 고객사는 공유 테이블에 RLS로 관리하는 하이브리드 접근이 효율적입니다. Next.js 미들웨어에서 서브도메인 또는 헤더로 테넌트를 식별하고, SET LOCAL app.tenant_id로 세션 변수를 설정하여 RLS 정책에서 참조합니다. 테넌트 온보딩 시 자동으로 스키마를 생성하는 프로비저닝 로직과, 테넌트별 백업/복원 전략도 필요합니다.

핵심 포인트
  • • Row-Level Security로 자동 필터링
  • • 대형/소형 테넌트 하이브리드 전략
  • • 세션 변수를 통한 테넌트 컨텍스트 전달
  • • 테넌트별 프로비저닝 및 백업 전략
답변에 넣으면 좋은 키워드
멀티 테넌시 Row-Level Security RLS 스키마 분리 테넌트 격리 하이브리드 전략
실무에서는

B2B SaaS, 클라우드 서비스, 교육 플랫폼 등에서 다수의 고객사를 효율적으로 관리하기 위해 멀티 테넌시 설계가 필수입니다.

Follow-up 질문

멀티 테넌시 환경에서 한 테넌트의 대량 쿼리가 다른 테넌트에 영향을 주는 Noisy Neighbor 문제를 해결하는 방법을 설명해주세요.

댓글 0

로그인 후 댓글을 작성할 수 있습니다.

아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!