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

Next.js 시니어 (7년+) 데이터베이스 5문항 조회수 29 · 2026-08-04 (화) 13:57:28
1 데이터베이스 모델링
Hard

Q. Next.js 기반 소셜 미디어 플랫폼에서 사용자 간 팔로우 관계와 게시물 피드를 효율적으로 제공하기 위한 데이터베이스 스키마를 설계해야 합니다. 팔로우 관계를 저장하는 테이블 구조, 피드 생성 전략(Fan-out on Write vs Fan-out on Read), 그리고 좋아요/댓글 등의 인터랙션 데이터 모델링 방안을 제시해주세요. 특히 수백만 명의 팔로워를 가진 인플루언서와 일반 사용자를 구분하여 처리하는 하이브리드 접근법을 포함해주세요.

팔로워 수에 따라 피드 생성 전략을 다르게 가져가는 것이 핵심입니다.

A. 모범답안

팔로우 관계는 users 테이블과 follows 테이블(follower_id, followee_id, created_at)로 다대다 관계를 구현합니다. 일반 사용자(팔로워 10만 이하)는 Fan-out on Write 방식으로 게시물 작성 시 각 팔로워의 feed 테이블에 미리 복사하여 읽기 성능을 최적화합니다. 인플루언서(팔로워 10만 이상)는 Fan-out on Read 방식으로 피드 조회 시 실시간으로 게시물을 가져와 쓰기 부하를 줄입니다. 좋아요는 likes 테이블(user_id, post_id, created_at)과 posts 테이블의 like_count 컬럼으로 이중화하여 집계 쿼리 부담을 줄이고, 댓글은 comments 테이블에 post_id와 parent_comment_id를 두어 대댓글을 지원하는 계층 구조로 설계합니다. Redis를 활용해 인기 게시물의 좋아요 수를 캐싱하고 주기적으로 DB와 동기화하여 쓰기 부하를 분산시킵니다.

핵심 포인트
  • • 팔로워 수 기준으로 Fan-out on Write와 Fan-out on Read를 하이브리드로 적용
  • • 좋아요 수를 별도 컬럼으로 비정규화하여 집계 성능 최적화
  • • 인플루언서와 일반 사용자를 구분하는 임계값 기반 전략
  • • Redis 캐싱으로 핫 데이터의 쓰기 부하 분산
답변에 넣으면 좋은 키워드
Fan-out on Write Fan-out on Read 비정규화 하이브리드 접근법 다대다 관계 집계 테이블
실무에서는

트위터, 인스타그램 같은 소셜 미디어에서 팔로워 수가 다양한 사용자들의 피드를 효율적으로 생성할 때 사용됩니다.

Follow-up 질문

피드 테이블이 수억 건으로 증가했을 때 파티셔닝 전략과 오래된 피드 데이터의 아카이빙 방안을 어떻게 설계하시겠습니까?

2 인덱스 최적화
Hard

Q. Next.js 전자상거래 사이트에서 상품 검색 쿼리가 느려지는 문제가 발생했습니다. products 테이블에는 1000만 건의 데이터가 있고, 사용자는 카테고리, 가격 범위, 브랜드, 평점, 재고 여부를 동시에 필터링합니다. 현재 각 컬럼에 단일 인덱스만 있는 상태에서, 복합 인덱스 설계 전략과 인덱스 컬럼 순서 결정 기준을 설명해주세요. 또한 인덱스가 사용되지 않는 경우(Index Scan vs Table Scan)와 커버링 인덱스를 활용한 최적화 방안을 포함해주세요.

필터 조건의 선택도(Selectivity)와 카디널리티(Cardinality)를 고려하여 인덱스 컬럼 순서를 결정해야 합니다.

A. 모범답안

복합 인덱스는 선택도가 높은(고유 값이 많은) 컬럼을 앞쪽에 배치하는 것이 원칙이므로, category_id, brand_id, price, rating, in_stock 순서로 구성합니다. 가격 범위 검색은 BETWEEN 연산자를 사용하므로 인덱스 중간에 배치하면 이후 컬럼은 인덱스를 타지 못하므로, 등호 조건(category, brand)을 앞에 두고 범위 조건(price)을 뒤에 배치합니다. 자주 조회되는 컬럼(name, image_url, price)을 인덱스에 포함시켜 커버링 인덱스를 구성하면 테이블 접근 없이 인덱스만으로 쿼리를 처리할 수 있습니다. EXPLAIN ANALYZE로 실행 계획을 분석하여 Index Scan이 발생하는지 확인하고, 함수 사용(LOWER, DATE)이나 OR 조건은 인덱스를 무효화하므로 쿼리를 재작성합니다. 인덱스 크기와 쓰기 성능 저하를 고려하여 실제 쿼리 패턴을 분석한 후 2-3개의 전략적 복합 인덱스만 유지합니다.

핵심 포인트
  • • 선택도와 카디널리티 기준으로 인덱스 컬럼 순서 결정
  • • 등호 조건을 앞에, 범위 조건을 뒤에 배치
  • • 커버링 인덱스로 테이블 접근 최소화
  • • EXPLAIN ANALYZE로 실행 계획 검증
  • • 인덱스 개수와 쓰기 성능 간 트레이드오프 고려
답변에 넣으면 좋은 키워드
복합 인덱스 선택도 카디널리티 커버링 인덱스 EXPLAIN ANALYZE Index Scan
실무에서는

대용량 상품 데이터에서 다중 필터 검색 성능을 최적화할 때 복합 인덱스 설계가 필수적입니다.

Follow-up 질문

부분 인덱스(Partial Index)와 표현식 인덱스(Expression Index)를 활용하여 인덱스 크기를 줄이면서도 성능을 유지하는 방법을 설명해주세요.

3 트랜잭션 및 동시성 제어
Hard

Q. Next.js 기반 티켓 예매 시스템에서 동일한 좌석에 대해 여러 사용자가 동시에 예매를 시도할 때 발생할 수 있는 동시성 문제와 해결 방안을 설명해주세요. 낙관적 락(Optimistic Lock)과 비관적 락(Pessimistic Lock)의 차이, 각각의 적용 시나리오, 그리고 PostgreSQL의 FOR UPDATE, FOR UPDATE SKIP LOCKED를 활용한 구현 방법을 포함해주세요. 또한 트랜잭션 격리 수준(Isolation Level)에 따른 영향도 함께 설명해주세요.

좌석 예매는 충돌이 자주 발생하는 시나리오이므로 비관적 락이 더 적합할 수 있습니다.

A. 모범답안

낙관적 락은 version 컬럼을 두고 UPDATE 시 version을 체크하여 충돌을 감지하는 방식으로, 충돌이 드문 경우에 적합하지만 티켓 예매처럼 동시 접근이 많으면 재시도가 빈번해져 비효율적입니다. 비관적 락은 SELECT FOR UPDATE로 행을 잠그는 방식으로, 트랜잭션이 끝날 때까지 다른 트랜잭션의 접근을 차단하여 데이터 일관성을 보장합니다. 티켓 예매는 BEGIN; SELECT * FROM seats WHERE id = ? AND status = 'available' FOR UPDATE; UPDATE seats SET status = 'reserved'; COMMIT; 패턴으로 구현하며, 좌석이 이미 잠겨있으면 대기하게 됩니다. FOR UPDATE SKIP LOCKED를 사용하면 잠긴 행은 건너뛰고 다음 가능한 좌석을 선택할 수 있어 대기 시간을 줄일 수 있습니다. 트랜잭션 격리 수준은 READ COMMITTED 이상을 사용해야 Dirty Read를 방지할 수 있으며, SERIALIZABLE은 팬텀 리드까지 방지하지만 성능 저하가 크므로 비관적 락과 READ COMMITTED 조합이 적절합니다.

핵심 포인트
  • • 낙관적 락은 충돌이 드문 경우, 비관적 락은 충돌이 빈번한 경우 적합
  • • SELECT FOR UPDATE로 행 수준 잠금 구현
  • • FOR UPDATE SKIP LOCKED로 대기 시간 최소화
  • • 트랜잭션 격리 수준과 락 전략의 조합
  • • Prisma/Drizzle에서 트랜잭션 API 활용
답변에 넣으면 좋은 키워드
낙관적 락 비관적 락 FOR UPDATE SKIP LOCKED 트랜잭션 격리 수준 행 수준 잠금
실무에서는

티켓 예매, 한정 수량 상품 구매, 좌석 선택 등 동시성 제어가 중요한 시스템에서 필수적으로 적용됩니다.

Follow-up 질문

분산 환경에서 여러 Next.js 인스턴스가 동시에 같은 DB에 접근할 때, 애플리케이션 레벨 락 대신 Redis를 활용한 분산 락 구현 방안을 설명해주세요.

4 쿼리 성능 튜닝
Medium

Q. Next.js 블로그 플랫폼에서 게시물 목록 조회 시 N+1 쿼리 문제가 발생하고 있습니다. 각 게시물마다 작성자 정보, 댓글 수, 좋아요 수를 함께 표시해야 하는데, 100개의 게시물을 조회할 때 300개 이상의 쿼리가 실행되어 응답 시간이 3초를 초과합니다. Prisma ORM을 사용할 때 N+1 문제를 해결하기 위한 방법들(include, select, aggregate)과 각 방법의 장단점, 그리고 쿼리 최적화를 위한 데이터베이스 스키마 개선 방안을 제시해주세요.

JOIN을 활용한 Eager Loading과 집계 데이터의 비정규화를 함께 고려해야 합니다.

A. 모범답안

Prisma의 include를 사용하여 posts를 조회할 때 author를 함께 가져오면 LEFT JOIN으로 처리되어 N+1 문제를 해결할 수 있습니다. 댓글 수와 좋아요 수는 _count 옵션으로 집계할 수 있지만, 매번 COUNT 쿼리를 실행하므로 성능이 떨어집니다. 이를 개선하려면 posts 테이블에 comment_count, like_count 컬럼을 추가하여 비정규화하고, 댓글이나 좋아요가 추가될 때 트리거나 애플리케이션 로직으로 카운터를 증가시킵니다. DataLoader 패턴을 적용하여 배치 로딩을 구현하면 여러 게시물의 관련 데이터를 한 번의 쿼리로 가져올 수 있습니다. 또한 select를 활용해 필요한 컬럼만 조회하고, 페이지네이션을 cursor 기반으로 변경하여 OFFSET의 성능 저하를 방지합니다. 자주 조회되는 데이터는 Redis에 캐싱하여 DB 부하를 줄이는 것도 효과적입니다.

핵심 포인트
  • • Prisma include로 관계 데이터 Eager Loading
  • • 집계 데이터를 컬럼으로 비정규화하여 COUNT 쿼리 제거
  • • DataLoader 패턴으로 배치 로딩 구현
  • • 필요한 컬럼만 select하여 데이터 전송량 최소화
  • • Redis 캐싱으로 반복 쿼리 제거
답변에 넣으면 좋은 키워드
N+1 쿼리 Eager Loading 비정규화 DataLoader Prisma include 집계 컬럼
실무에서는

ORM을 사용하는 대부분의 웹 애플리케이션에서 관계 데이터를 조회할 때 N+1 문제가 발생하며, 이를 해결하지 않으면 성능이 급격히 저하됩니다.

Follow-up 질문

게시물 목록에 각 게시물의 최근 댓글 3개를 함께 표시해야 할 때, 서브쿼리와 윈도우 함수를 활용한 최적화 방법을 설명해주세요.

5 데이터베이스 아키텍처
Hard

Q. Next.js 기반 글로벌 SaaS 서비스에서 읽기 트래픽이 쓰기 트래픽의 10배 이상이며, 특정 시간대에 DB CPU 사용률이 90%를 초과하는 문제가 발생했습니다. Read Replica를 도입하여 읽기 부하를 분산하는 아키텍처를 설계할 때, Primary-Replica 간 복제 지연(Replication Lag) 처리 방법, Server Components와 Server Actions에서의 읽기/쓰기 라우팅 전략, 그리고 eventual consistency를 허용할 수 있는 데이터와 strong consistency가 필요한 데이터의 구분 기준을 설명해주세요.

읽기와 쓰기를 명확히 분리하고, 데이터 특성에 따라 일관성 요구사항을 다르게 가져가야 합니다.

A. 모범답안

Primary DB는 모든 쓰기와 강한 일관성이 필요한 읽기를 처리하고, Read Replica는 목록 조회, 통계, 검색 등 eventual consistency를 허용할 수 있는 읽기를 처리하도록 분리합니다. Prisma에서는 replica 옵션으로 읽기 전용 클라이언트를 별도로 구성하고, Server Components에서는 기본적으로 Replica를 사용하며 Server Actions의 쓰기 후 즉시 읽기가 필요한 경우만 Primary를 사용합니다. 복제 지연은 평균 100-500ms 정도 발생하므로, 사용자가 방금 작성한 데이터를 조회할 때는 Primary를 사용하거나 세션 ID 기반으로 일정 시간 동안 Primary로 라우팅합니다. 주문 내역, 결제 정보, 사용자 인증은 strong consistency가 필요하므로 Primary에서만 읽고, 상품 목록, 댓글, 조회수는 eventual consistency를 허용하여 Replica를 사용합니다. 복제 지연을 모니터링하여 임계값을 초과하면 알림을 보내고, 필요시 Replica를 추가하거나 Read-only 트래픽을 캐시로 우회시킵니다.

핵심 포인트
  • • Primary-Replica 구조로 읽기/쓰기 분리
  • • 데이터 특성에 따라 strong/eventual consistency 구분
  • • 복제 지연 시간을 고려한 라우팅 전략
  • • 쓰기 후 즉시 읽기는 Primary 사용
  • • Prisma replica 옵션으로 읽기 전용 클라이언트 구성
답변에 넣으면 좋은 키워드
Read Replica Primary-Replica Replication Lag eventual consistency strong consistency 읽기/쓰기 분리
실무에서는

대규모 트래픽을 처리하는 서비스에서 DB 병목을 해결하기 위해 읽기 복제본을 활용하는 것은 표준 아키텍처 패턴입니다.

Follow-up 질문

Multi-Region 환경에서 지역별로 Read Replica를 배치하고, 사용자의 지리적 위치에 따라 가장 가까운 Replica로 라우팅하는 아키텍처를 어떻게 구현하시겠습니까?

댓글 0

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

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