[강의] 대규모 시스템 설계 내용 정리 (1)

유기훈·2025년 10월 7일

🏗️ 대규모 시스템 설계 강의 정리 (섹션 2)

인프런 강의 섹션 2: 데이터베이스 구조와 확장 전략 학습 내용 정리

기간: 8월 18일 ~ 8월 26일


📅 8월 18일 (월) — 샤딩(Sharding)

🔹 샤딩이란?

  • 데이터를 여러 DB에 분산 저장하는 기술
  • 가용성을 높이기 위한 Master-Slave 구조와는 목적이 다름
  • 샤딩은 데이터 분산과 확장성을 위한 구조

🔹 샤딩의 종류

  • 수직 샤딩(Vertical Sharding): 테이블 단위로 기능별 DB 분리 예) 사용자, 결제, 게시판 DB를 각각 분리
  • 수평 샤딩(Horizontal Sharding): 한 테이블의 데이터를 여러 DB에 나누어 저장 예) user_id 범위별로 다른 DB에 저장

🔹 샤딩 키(Sharding Key)의 중요성

  • 어떤 기준으로 데이터를 분산할지 결정하는 핵심 포인트
  • 잘못된 샤딩 키는 전체 DB를 탐색하게 만들어 성능 저하 유발
  • 예시:
    • DC Inside 같은 게시판 구조
    • “야구 갤러리”의 글과 댓글 데이터가 있을 때, → 게시판 ID(board_id)를 샤딩 키로 설정하는 것이 효율적
    • 만약 글 ID(article_id)를 샤딩 키로 쓴다면, 특정 게시판 조회 시 모든 DB를 뒤져야 할 수도 있음

🔹 AWS DynamoDB의 사례

  • DynamoDB는 해싱 키만 지정하면 내부적으로 샤딩을 자동 처리
  • 애플리케이션에서 직접 샤딩 로직을 구현할 필요가 없음

🔹 PK 생성 전략: Snowflake 알고리즘

  • 오름차순 + 유니크한 숫자를 생성하는 알고리즘
  • 분산 환경에서 충돌 없이 정렬 가능한 ID 생성 가능
  • 이후 강의에서 자세히 다룸

📅 8월 21일 (목) — 인덱스 구조와 페이지네이션

🔹 InnoDB 인덱스 구조

  • InnoDB는 테이블마다 Clustered Index를 자동 생성
  • Clustered Index의 leaf node는 실제 행 데이터(row)를 저장
  • 일반적으로 Primary Key가 Clustered Index로 설정됨
  • 우리가 생성하는 인덱스는 Secondary Index
구분Leaf Node 내용데이터 접근 방식
Clustered Index실제 Row 데이터직접 접근
Secondary Index인덱스 컬럼 + PK 포인터PK → Row 접근

🔹 커버링 인덱스(Covering Index)

  • 조회 쿼리에서 필요한 컬럼이 모두 인덱스에 포함되어, 테이블 접근 없이 인덱스만으로 조회 가능한 경우
SELECT *
FROM (
    SELECT article_id
    FROM article
    WHERE board_id = 1
    ORDER BY article_id DESC
    LIMIT 30 OFFSET 149970
) t
LEFT JOIN article ON t.article_id = article.article_id;

→ 서브쿼리에서 커버링 인덱스를 사용하고, 본 테이블을 LEFT JOIN하는 방식

🔹 Offset 기반 페이지네이션의 한계

  • Offset이 클수록 Index Scan 비용이 증가
  • 실제 데이터 접근 없이 인덱스만 타더라도 느려질 수밖에 없음

🔹 개선 방안

  1. 데이터 분리

    • 예: 게시글을 연도별 테이블로 분리 (article_2024, article_2025 등)
  2. 메타데이터 관리

    • 테이블별 게시글 개수를 미리 저장 → offset 범위 벗어나면 테이블 스킵
  3. 정책적 제약

    • 일정 기간 이전의 데이터는 조회 불가

📅 8월 23일 (토) — Count 쿼리 최적화

🔹 페이지 번호 기반 페이지네이션의 문제

  • 게시글 개수를 표시하기 위해 COUNT(*) 쿼리를 실행
  • 커버링 인덱스를 사용하더라도, 모든 게시글 수를 세야 하므로 느림

🔹 꼭 전체 개수가 필요할까?

  • 대부분의 서비스는 최대 이동 가능한 페이지 수가 제한됨
  • 예: 현재 1페이지에서 1~10페이지만 이동 가능

🔹 페이지 계산 공식

최대 이동 가능한 페이지 수(k), 현재 페이지(n), 페이지당 게시글 수(m)

(((n - 1) / k) + 1) * m * k + 1

🔹 Count 쿼리 최적화 예시

SELECT COUNT(*)
FROM (
    SELECT article_id
    FROM article
    WHERE board_id = {board_id}
    LIMIT {limit}
) t;

→ 일부 데이터만 대상으로 count 수행 (성능 개선)


📅 8월 26일 (화) — PK 생성 전략

🔹 1. DB Auto Increment

  • 단일 DB에서는 간편하지만, 분산 환경에서는 PK 중복 발생 가능
  • 클라이언트 노출 시 보안 이슈 발생
  • UUID를 별도 Unique Index로 사용하는 것도 가능하나,
    • Secondary → Clustered Index 접근이 필요해 조회 비용 증가

🔹 2. 유니크 문자열 / 난수 (UUID 등)

  • UUID, Random String 등을 PK로 지정 가능
  • 하지만 랜덤성으로 인해 성능 저하 발생
    • Clustered Index는 정렬 구조 유지 필요 → 중간 삽입 시 B+ Tree 재구성 발생
    • 범위 조회 시 랜덤 I/O 증가

🔹 3. 유니크 정렬 문자열 (예: ULID)

  • 분산 환경에서도 중복 없음
  • 정렬 가능 → 랜덤 I/O 감소
  • 보안성도 확보
  • 일반적으로 128비트 사용 → 데이터 크기에 따라 성능/공간 트레이드오프 존재

🔹 4. 유니크 정렬 숫자 (예: Snowflake)

  • 64비트 정렬 숫자 기반 ID 생성 알고리즘
  • 분산 환경 중복 문제 해결
  • 정렬 및 유니크 보장
  • 대규모 시스템에서 PK로 널리 사용됨 (Twitter, Kakao 등)

🧭 마무리

이번 섹션에서는 데이터베이스 확장성과 인덱스 구조, PK 설계 전략을 중심으로 다뤘습니다.

단순히 쿼리 튜닝을 넘어, 데이터가 커질 때 시스템이 어떻게 확장될 수 있는지를 고민하게 되는 구간입니다.

🔗 참고 링크: Perplexity 검색 결과


노트에 정리해둔 내용 GPT 사용하여 재정리함

profile
개발 블로그

0개의 댓글