kt-event-marketing/design/backend/database/distribution-service.md
jhbkjh 3075a5d49f 물리아키텍처 설계 완료
 주요 기능
- Azure 기반 물리아키텍처 설계 (개발환경/운영환경)
- 7개 마이크로서비스 물리 구조 설계
- 네트워크 아키텍처 다이어그램 작성 (Mermaid)
- 환경별 비교 분석 및 마스터 인덱스 문서

📁 생성 파일
- design/backend/physical/physical-architecture.md (마스터)
- design/backend/physical/physical-architecture-dev.md (개발환경)
- design/backend/physical/physical-architecture-prod.md (운영환경)
- design/backend/physical/*.mmd (4개 Mermaid 다이어그램)

🎯 핵심 성과
- 비용 최적화: 개발환경 월 $143, 운영환경 월 $2,860
- 확장성: 개발환경 100명 → 운영환경 10,000명 (100배)
- 가용성: 개발환경 95% → 운영환경 99.9%
- 보안: 다층 보안 아키텍처 (L1~L4)

🛠️ 기술 스택
- Azure Kubernetes Service (AKS)
- Azure Database for PostgreSQL Flexible
- Azure Cache for Redis Premium
- Azure Service Bus Premium
- Application Gateway + WAF

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 15:13:01 +09:00

11 KiB

Distribution Service 데이터베이스 설계서

📋 데이터설계 요약

설계 개요

  • 서비스명: Distribution Service
  • 아키텍처 패턴: Layered Architecture
  • 데이터베이스: PostgreSQL (배포 상태 영구 저장), Redis (실시간 모니터링)
  • 설계 일시: 2025-10-29
  • 설계자: Backend Developer (최수연 "아키텍처")

데이터 특성

  • 배포 상태 관리: 이벤트별 다중 채널 배포 상태 추적
  • 채널 독립성: 6개 채널(TV, CALL, SNS)별 독립적 상태 관리
  • 실시간 모니터링: Redis 캐시를 통한 배포 진행 상태 실시간 조회
  • 성과 추적: 채널별 도달률(estimatedViews), 완료 시간, 재시도 횟수 추적
  • 에러 관리: 채널별 에러 메시지, 재시도 정보 저장

주요 테이블

  1. distribution_status: 배포 전체 상태 관리 (이벤트 ID, 전체 상태, 시작/완료 시간)
  2. channel_status: 채널별 세부 배포 상태 (채널 타입, 진행률, 배포 ID, 도달률, 에러 정보)

캐시 설계

  • event:{eventId}:distribution: 배포 상태 실시간 조회 (TTL: 1시간)
  • distribution:channel:{eventId}:{channel}: 채널별 상태 캐시 (TTL: 30분)

1. 데이터베이스 스키마 설계

1.1 PostgreSQL 테이블 설계

1.1.1 distribution_status (배포 상태 테이블)

테이블 목적: 이벤트별 배포 전체 상태 관리

컬럼명 타입 NULL 기본값 설명
id BIGSERIAL NO - 배포 상태 ID (PK)
event_id VARCHAR(36) NO - 이벤트 ID (UUID)
overall_status VARCHAR(20) NO - 전체 배포 상태 (IN_PROGRESS, COMPLETED, FAILED, PARTIAL_SUCCESS)
started_at TIMESTAMP NO - 배포 시작 시간
completed_at TIMESTAMP YES NULL 배포 완료 시간
created_at TIMESTAMP NO CURRENT_TIMESTAMP 생성 시간
updated_at TIMESTAMP NO CURRENT_TIMESTAMP 수정 시간

제약 조건:

  • PRIMARY KEY: id
  • UNIQUE KEY: event_id (이벤트당 하나의 배포 상태만 존재)
  • INDEX: event_id (조회 성능 최적화)
  • CHECK: overall_status IN ('IN_PROGRESS', 'COMPLETED', 'FAILED', 'PARTIAL_SUCCESS')

1.1.2 channel_status (채널 배포 상태 테이블)

테이블 목적: 채널별 세부 배포 상태 및 성과 추적

컬럼명 타입 NULL 기본값 설명
id BIGSERIAL NO - 채널 상태 ID (PK)
distribution_status_id BIGINT NO - 배포 상태 ID (FK)
channel VARCHAR(20) NO - 채널 타입 (URIDONGNETV, RINGOBIZ, GINITV, INSTAGRAM, NAVER, KAKAO)
status VARCHAR(20) NO - 채널 배포 상태 (PENDING, IN_PROGRESS, SUCCESS, FAILED)
progress INTEGER YES 0 진행률 (0-100)
distribution_id VARCHAR(100) YES NULL 채널별 배포 ID (외부 시스템 ID)
estimated_views INTEGER YES 0 예상 도달률 (조회수)
update_timestamp TIMESTAMP NO CURRENT_TIMESTAMP 상태 업데이트 시간
event_id VARCHAR(36) NO - 이벤트 ID (조회 최적화용)
impression_schedule TEXT YES NULL 노출 일정 (JSON 배열)
post_url VARCHAR(500) YES NULL 게시물 URL
post_id VARCHAR(100) YES NULL 게시물 ID
message_id VARCHAR(100) YES NULL 메시지 ID (카카오톡)
completed_at TIMESTAMP YES NULL 채널 배포 완료 시간
error_message TEXT YES NULL 에러 메시지
retries INTEGER YES 0 재시도 횟수
last_retry_at TIMESTAMP YES NULL 마지막 재시도 시간
created_at TIMESTAMP NO CURRENT_TIMESTAMP 생성 시간
updated_at TIMESTAMP NO CURRENT_TIMESTAMP 수정 시간

제약 조건:

  • PRIMARY KEY: id
  • FOREIGN KEY: distribution_status_id REFERENCES distribution_status(id) ON DELETE CASCADE
  • UNIQUE KEY: (distribution_status_id, channel) - 배포당 채널별 하나의 상태만 존재
  • INDEX: event_id (이벤트별 조회 최적화)
  • INDEX: (event_id, channel) (채널별 조회 최적화)
  • INDEX: status (상태별 조회 최적화)
  • CHECK: channel IN ('URIDONGNETV', 'RINGOBIZ', 'GINITV', 'INSTAGRAM', 'NAVER', 'KAKAO')
  • CHECK: status IN ('PENDING', 'IN_PROGRESS', 'SUCCESS', 'FAILED')
  • CHECK: progress BETWEEN 0 AND 100

1.2 Redis 캐시 설계

1.2.1 배포 상태 캐시

키 패턴: event:{eventId}:distribution

데이터 구조: Hash

{
  "eventId": "uuid",
  "overallStatus": "IN_PROGRESS",
  "startedAt": "2025-10-29T10:00:00",
  "completedAt": null,
  "successCount": 3,
  "failureCount": 1,
  "totalChannels": 6
}

TTL: 1시간 (3600초)

사용 목적:

  • 배포 상태 실시간 조회 성능 최적화
  • DB 부하 감소 (조회 빈도가 높은 데이터)
  • 배포 진행 중 빠른 상태 업데이트

1.2.2 채널별 상태 캐시

키 패턴: distribution:channel:{eventId}:{channel}

데이터 구조: Hash

{
  "channel": "INSTAGRAM",
  "status": "IN_PROGRESS",
  "progress": 75,
  "distributionId": "ig_post_12345",
  "estimatedViews": 5000,
  "updateTimestamp": "2025-10-29T10:30:00",
  "postUrl": "https://instagram.com/p/abc123",
  "errorMessage": null
}

TTL: 30분 (1800초)

사용 목적:

  • 채널별 배포 상태 실시간 모니터링
  • 진행률 추적 및 업데이트
  • 외부 API 호출 결과 임시 저장

2. Entity-Table 매핑

2.1 DistributionStatus Entity → distribution_status Table

Entity 필드 테이블 컬럼 매핑
id id 1:1
eventId event_id 1:1
overallStatus overall_status 1:1
startedAt started_at 1:1
completedAt completed_at 1:1
channels (관계) 1:N → channel_status
createdAt created_at 1:1 (BaseTimeEntity)
updatedAt updated_at 1:1 (BaseTimeEntity)

2.2 ChannelStatusEntity Entity → channel_status Table

Entity 필드 테이블 컬럼 매핑
id id 1:1
distributionStatus distribution_status_id N:1 (FK)
channel channel 1:1 (Enum)
status status 1:1
progress progress 1:1
distributionId distribution_id 1:1
estimatedViews estimated_views 1:1
updateTimestamp update_timestamp 1:1
eventId event_id 1:1
impressionSchedule impression_schedule 1:1 (JSON String)
postUrl post_url 1:1
postId post_id 1:1
messageId message_id 1:1
completedAt completed_at 1:1
errorMessage error_message 1:1
retries retries 1:1
lastRetryAt last_retry_at 1:1
createdAt created_at 1:1 (BaseTimeEntity)
updatedAt updated_at 1:1 (BaseTimeEntity)

3. 데이터 관계

3.1 테이블 간 관계

distribution_status (1) ----< (N) channel_status
  - 하나의 배포 상태는 여러 채널 상태를 가짐
  - CASCADE DELETE: 배포 상태 삭제 시 채널 상태도 함께 삭제

3.2 인덱스 전략

distribution_status 테이블:

  • PRIMARY KEY: id (클러스터 인덱스)
  • UNIQUE INDEX: event_id (이벤트별 배포 상태 유일성 보장)

channel_status 테이블:

  • PRIMARY KEY: id (클러스터 인덱스)
  • UNIQUE INDEX: (distribution_status_id, channel) (배포당 채널별 유일성)
  • INDEX: event_id (이벤트별 채널 상태 조회 최적화)
  • INDEX: (event_id, channel) (복합 조회 최적화)
  • INDEX: status (상태별 필터링 최적화)

4. 데이터 독립성 설계

4.1 서비스 간 데이터 분리

Distribution Service 데이터 소유권:

  • 배포 상태 및 채널별 성과 데이터 완전 소유
  • 타 서비스의 데이터를 직접 조회하지 않음

타 서비스 데이터 참조:

  • Event ID: Event Service에서 생성한 ID를 참조 (FK 없음)
  • User ID: 직접 저장하지 않음 (인증 정보로만 사용)
  • 참조 방식: Redis 캐시 또는 Kafka 이벤트로만 참조

4.2 데이터 동기화 전략

Kafka 이벤트 발행:

// 배포 완료 시 이벤트 발행
Topic: distribution-completed
Event: {
  "eventId": "uuid",
  "distributedChannels": [
    {
      "channel": "INSTAGRAM",
      "status": "SUCCESS",
      "expectedViews": 5000
    }
  ],
  "completedAt": "2025-10-29T11:00:00"
}

Analytics Service 연동:

  • Distribution Service → Kafka → Analytics Service
  • 채널별 성과 데이터 비동기 전달
  • 장애 격리 보장 (Circuit Breaker)

5. 쿼리 성능 최적화

5.1 조회 쿼리 최적화

이벤트별 배포 상태 조회:

-- 인덱스 활용: event_id
SELECT ds.*, cs.*
FROM distribution_status ds
LEFT JOIN channel_status cs ON ds.id = cs.distribution_status_id
WHERE ds.event_id = ?;

채널별 배포 현황 조회:

-- 인덱스 활용: (event_id, channel)
SELECT *
FROM channel_status
WHERE event_id = ? AND channel = ?;

진행 중인 배포 목록 조회:

-- 인덱스 활용: overall_status
SELECT *
FROM distribution_status
WHERE overall_status = 'IN_PROGRESS'
ORDER BY started_at DESC;

5.2 캐시 전략

조회 우선순위:

  1. Redis 캐시 조회 시도
  2. 캐시 미스 시 PostgreSQL 조회
  3. 조회 결과를 Redis에 캐싱

캐시 무효화:

  • 배포 상태 업데이트 시 캐시 갱신
  • 배포 완료 시 캐시 TTL 연장 (1시간 → 24시간)
  • 채널 상태 변경 시 해당 채널 캐시 갱신

6. 데이터 보안 및 제약

6.1 데이터 무결성

NOT NULL 제약:

  • 필수 정보: event_id, channel, status, overall_status
  • 시간 정보: started_at, update_timestamp

CHECK 제약:

  • overall_status: 4가지 상태만 허용
  • channel: 6개 채널 타입만 허용
  • status: 4가지 배포 상태만 허용
  • progress: 0-100 범위 제한

UNIQUE 제약:

  • event_id: 이벤트당 하나의 배포 상태
  • (distribution_status_id, channel): 배포당 채널별 하나의 상태

6.2 CASCADE 정책

ON DELETE CASCADE:

  • distribution_status 삭제 시 channel_status 자동 삭제
  • 데이터 일관성 보장

7. 마이그레이션 전략

7.1 초기 데이터 마이그레이션

  • 초기 배포 시 기본 데이터 없음 (운영 데이터만 존재)
  • 채널 타입 Enum 검증 데이터 확인

7.2 스키마 변경 전략

  • Flyway 또는 Liquibase를 통한 버전 관리
  • 무중단 배포를 위한 Blue-Green 전략
  • 인덱스 추가 시 CONCURRENTLY 옵션 사용

8. 모니터링 및 유지보수

8.1 성능 모니터링 지표

  • 배포 상태 조회 응답 시간 (<100ms)
  • 채널별 배포 성공률 (>95%)
  • 재시도 횟수 평균 (<2회)
  • 캐시 히트율 (>80%)

8.2 데이터 정리 정책

  • 완료된 배포 상태: 30일 후 아카이빙
  • 실패한 배포 로그: 90일 보관
  • Redis 캐시: TTL 자동 만료

9. 참고 자료

9.1 관련 문서

  • 클래스 설계서: design/backend/class/distribution-service.puml
  • API 설계서: design/backend/api/distribution-service-api.md
  • 시퀀스 다이어그램: design/backend/sequence/inner/distribution-service-*.puml

9.2 외부 참조


문서 버전: v1.0 작성일: 2025-10-29 작성자: Backend Developer (최수연 "아키텍처")