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

8.8 KiB

User Service 데이터베이스 설계서

데이터 설계 요약

📋 설계 개요

  • 서비스명: user-service
  • 데이터베이스: PostgreSQL 16
  • 캐시 DB: Redis 7
  • 테이블 수: 2개 (users, stores)
  • 인덱스 수: 5개
  • 설계 원칙: 마이크로서비스 데이터 독립성 원칙 준수

🎯 핵심 특징

  • 독립 데이터베이스: user-service만의 독립적인 스키마
  • 1:1 Entity 매핑: 클래스 설계서의 User, Store Entity와 정확히 일치
  • JWT 기반 인증: Redis를 활용한 세션 및 Blacklist 관리
  • 성능 최적화: 조회 패턴 기반 인덱스 설계
  • 보안: 비밀번호 bcrypt 암호화, 민감 정보 암호화 저장

1. 테이블 설계

1.1 users 테이블

목적: 사용자(소상공인) 정보 관리

컬럼명 타입 제약조건 설명
id UUID PK 사용자 고유 식별자
name VARCHAR(100) NOT NULL 사용자 이름
phone_number VARCHAR(20) NOT NULL, UNIQUE 전화번호 (중복 검증)
email VARCHAR(255) NOT NULL, UNIQUE 이메일 (로그인 ID)
password_hash VARCHAR(255) NOT NULL bcrypt 암호화된 비밀번호
role VARCHAR(20) NOT NULL 사용자 역할 (OWNER, ADMIN)
status VARCHAR(20) NOT NULL, DEFAULT 'ACTIVE' 계정 상태
last_login_at TIMESTAMP NULL 최종 로그인 시각
created_at TIMESTAMP NOT NULL, DEFAULT NOW() 생성 시각
updated_at TIMESTAMP NOT NULL, DEFAULT NOW() 수정 시각

제약조건:

  • PRIMARY KEY: id
  • UNIQUE: email, phone_number
  • CHECK: role IN ('OWNER', 'ADMIN')
  • CHECK: status IN ('ACTIVE', 'INACTIVE', 'LOCKED', 'WITHDRAWN')

인덱스:

  • idx_users_email: 로그인 조회 최적화
  • idx_users_phone_number: 전화번호 중복 검증 최적화
  • idx_users_status: 활성 사용자 필터링 최적화

1.2 stores 테이블

목적: 가게(매장) 정보 관리

컬럼명 타입 제약조건 설명
id UUID PK 가게 고유 식별자
user_id UUID NOT NULL, UNIQUE, FK 사용자 ID (1:1 관계)
name VARCHAR(200) NOT NULL 가게 이름
industry VARCHAR(100) NOT NULL 업종
address VARCHAR(500) NOT NULL 주소
business_hours TEXT NULL 영업시간
created_at TIMESTAMP NOT NULL, DEFAULT NOW() 생성 시각
updated_at TIMESTAMP NOT NULL, DEFAULT NOW() 수정 시각

제약조건:

  • PRIMARY KEY: id
  • FOREIGN KEY: user_id REFERENCES users(id) ON DELETE CASCADE
  • UNIQUE: user_id (1:1 관계 보장)

인덱스:

  • idx_stores_user_id: User-Store 조인 최적화

2. 관계 설계

2.1 User ↔ Store (1:1 양방향)

users(1) ---- (1)stores
       └─ user_id FK

관계 특성:

  • Type: One-to-One Bidirectional
  • Owner: Store (FK를 소유)
  • Cascade: ALL (User 삭제 시 Store도 삭제)
  • Lazy Loading: User 조회 시 Store는 지연 로딩

비즈니스 규칙:

  • 하나의 User는 최대 하나의 Store만 소유
  • Store는 반드시 User에 속해야 함 (NOT NULL FK)
  • User 삭제 시 Store도 함께 삭제 (CASCADE)

3. 인덱스 설계

3.1 인덱스 목록

인덱스명 테이블 컬럼 목적 유형
idx_users_email users email 로그인 조회 UNIQUE
idx_users_phone_number users phone_number 중복 검증 UNIQUE
idx_users_status users status 활성 사용자 필터링 B-tree
idx_stores_user_id stores user_id User-Store 조인 UNIQUE

3.2 조회 패턴 분석

빈번한 조회 패턴:

  1. 로그인: SELECT * FROM users WHERE email = ? → idx_users_email
  2. 중복 검증: SELECT COUNT(*) FROM users WHERE phone_number = ? → idx_users_phone_number
  3. 프로필 조회: SELECT u.*, s.* FROM users u LEFT JOIN stores s ON u.id = s.user_id WHERE u.id = ?
  4. 활성 사용자: SELECT * FROM users WHERE status = 'ACTIVE' → idx_users_status

4. Redis 캐시 설계

4.1 JWT 세션 관리

키 패턴: session:{token}

데이터 구조:

{
  "userId": "UUID",
  "role": "OWNER|ADMIN",
  "email": "user@example.com",
  "expiresAt": "timestamp"
}

TTL: JWT 만료 시간과 동일 (예: 7일)

목적:

  • JWT 토큰 검증 시 DB 조회 방지
  • 빠른 인증 처리
  • 로그아웃 시 세션 삭제

4.2 JWT Blacklist

키 패턴: blacklist:{token}

데이터 구조:

{
  "userId": "UUID",
  "logoutAt": "timestamp"
}

TTL: 토큰 원래 만료 시간까지

목적:

  • 로그아웃된 토큰 재사용 방지
  • 유효한 토큰이지만 무효화된 토큰 관리
  • 보안 강화

5. 데이터 무결성 및 보안

5.1 제약조건

NOT NULL 제약:

  • 필수 필드: name, email, password_hash, role, status
  • Store 필수 필드: user_id, name, industry, address

UNIQUE 제약:

  • email: 로그인 ID 중복 방지
  • phone_number: 전화번호 중복 방지
  • stores.user_id: 1:1 관계 보장

CHECK 제약:

  • role: OWNER, ADMIN만 허용
  • status: ACTIVE, INACTIVE, LOCKED, WITHDRAWN만 허용

FOREIGN KEY 제약:

  • stores.user_id → users.id (ON DELETE CASCADE)

5.2 보안

비밀번호 보안:

  • bcrypt 알고리즘 사용 (cost factor 12)
  • password_hash 컬럼에 저장
  • 원본 비밀번호는 저장하지 않음

민감 정보 보호:

  • 전화번호, 이메일: 암호화 고려 (필요시)
  • 주소: 개인정보이므로 접근 제어

6. 성능 최적화 전략

6.1 인덱스 전략

단일 컬럼 인덱스:

  • email, phone_number: UNIQUE 인덱스로 조회 및 중복 검증
  • status: 활성 사용자 필터링

복합 인덱스 검토:

  • 현재는 불필요 (단순 조회 패턴)
  • 추후 복잡한 검색 조건 추가 시 고려

6.2 캐시 전략

Redis 활용:

  • JWT 세션: DB 조회 없이 인증 처리
  • Blacklist: 로그아웃 토큰 빠른 검증

캐시 갱신:

  • 프로필 수정 시 세션 캐시 갱신
  • 비밀번호 변경 시 모든 세션 무효화

6.3 쿼리 최적화

N+1 문제 방지:

  • User 조회 시 Store LEFT JOIN으로 한 번에 조회
  • JPA: @OneToOne(fetch = FetchType.LAZY) + 필요시 fetch join

배치 처리:

  • 대량 사용자 조회 시 IN 절 활용
  • 페이징 처리: LIMIT/OFFSET 또는 커서 기반

7. 확장성 고려사항

7.1 수직 확장 (Scale-Up)

현재 설계로 충분:

  • 예상 사용자: 10만 명 이하
  • 단순한 스키마 구조
  • 효율적인 인덱스

7.2 수평 확장 (Scale-Out)

샤딩 전략 (필요 시):

  • 샤딩 키: user_id (UUID 기반)
  • 읽기 복제본: 조회 성능 향상
  • Redis Cluster: 세션 분산 저장

7.3 데이터 증가 대응

파티셔닝:

  • 현재는 불필요
  • 수백만 사용자 이상 시 status별 파티셔닝 고려

아카이빙:

  • WITHDRAWN 사용자 데이터 아카이빙
  • 1년 이상 비활성 사용자 별도 테이블 이관

8. 백업 및 복구 전략

8.1 백업

PostgreSQL:

  • 일일 전체 백업 (pg_dump)
  • WAL 아카이빙 (Point-in-Time Recovery)
  • 보관 기간: 30일

Redis:

  • RDB 스냅샷: 1시간마다
  • AOF 로그: appendfsync everysec
  • 보관 기간: 7일

8.2 복구

재해 복구 목표:

  • RPO (Recovery Point Objective): 1시간
  • RTO (Recovery Time Objective): 30분

복구 절차:

  1. PostgreSQL: WAL 기반 특정 시점 복구
  2. Redis: RDB + AOF 조합 복구
  3. 세션 재생성: 사용자 재로그인

9. 모니터링 및 알림

9.1 모니터링 항목

데이터베이스:

  • Connection Pool 사용률
  • Slow Query (1초 이상)
  • 인덱스 사용률
  • 테이블 크기 증가율

캐시:

  • Redis 메모리 사용률
  • 캐시 히트율
  • Eviction 발생 빈도

9.2 알림 임계값

Critical:

  • Connection Pool 사용률 > 90%
  • Slow Query > 10건/분
  • Redis 메모리 사용률 > 90%

Warning:

  • Connection Pool 사용률 > 70%
  • Slow Query > 5건/분
  • 캐시 히트율 < 80%

10. 마이그레이션 및 버전 관리

10.1 스키마 버전 관리

도구: Flyway 또는 Liquibase

마이그레이션 파일:

  • V1__create_users_table.sql
  • V2__create_stores_table.sql
  • V3__add_indexes.sql

10.2 무중단 마이그레이션

컬럼 추가:

  1. 새 컬럼 추가 (NULL 허용)
  2. 애플리케이션 배포
  3. 데이터 마이그레이션
  4. NOT NULL 제약 추가

컬럼 삭제:

  1. 애플리케이션에서 사용 중단
  2. 배포 및 검증
  3. 컬럼 삭제

11. 참고 자료

  • 클래스 설계서: design/backend/class/user-service.puml
  • 공통 컴포넌트: design/backend/class/common-base.puml
  • ERD: design/backend/database/user-service-erd.puml
  • 스키마: design/backend/database/user-service-schema.psql