ID: key_26_22_05_25_18_02_00_00000 Created date: 5월 25 2026 월요일, 22주 18:00

연관 문서


개요

DB 관련 정의는 befw-app-server 레포의 CLAUDE.md에 함께 기재하거나,
별도 DATABASE.md 파일로 관리한다.
Claude Code는 이 내용을 기반으로 DDL / 마이그레이션 파일을 생성한다.


프로젝트 파일 위치

befw-app-server/
├── CLAUDE.md                            ← DB 컨벤션 포함
└── src/main/resources/
    └── db/
        └── migration/
            ├── V1__create_users.sql     ← Flyway 마이그레이션 파일
            ├── V2__create_projects.sql
            ├── V3__create_issues.sql
            └── ...

Flyway 미사용 시 Liquibase (changelog.xml) 또는 직접 SQL 관리 방식 선택 필요


CLAUDE.md 정의 항목 및 예시

1. 마이그레이션 도구

## DB Migration Tool
- 도구: Flyway
- 파일 위치: src/main/resources/db/migration/
- 네이밍 규칙: V{버전}__{설명}.sql (예: V3__create_issues.sql)
- 실행 방식: Spring Boot 기동 시 자동 적용

작성 필요: Flyway / Liquibase / 직접 관리 중 선택


2. 테이블 네이밍 컨벤션

## Table Convention
- 테이블명: snake_case 복수형 (예: users, project_members)
- 컬럼명: snake_case (예: created_at, project_id)
- PK: id (BIGSERIAL 또는 UUID)
- FK: {참조테이블단수형}_id (예: project_id, user_id)
- 생성/수정 시각: created_at TIMESTAMPTZ, updated_at TIMESTAMPTZ (모든 테이블)

작성 필요: UUID vs BIGSERIAL PK 방식 결정


3. PK 전략

## Primary Key Strategy
- 방식: BIGSERIAL (자동증가 정수) 또는 UUID
- 결정값: UUID (gen_random_uuid())    ← 결정 후 하나만 기재
- 이유: 분산 환경 대비, 보안상 순번 노출 방지

작성 필요: 팀 방식에 맞게 결정


4. Soft Delete 정책

## Soft Delete Policy
- 정책: deleted_at TIMESTAMPTZ NULL 사용
- NULL = 정상, NOT NULL = 삭제됨
- 조회 시 항상 WHERE deleted_at IS NULL 조건 포함
- 물리 삭제 금지 (audit_logs 참조 무결성 유지)

작성 필요: deleted_at vs is_deleted BOOLEAN 중 결정


5. 인덱스 전략

## Index Strategy
- FK 컬럼 전체에 인덱스 필수 (project_id, user_id, issue_id 등)
- 조회 빈도 높은 컬럼 복합 인덱스 적용
  예: idx_issues_project_status ON issues(project_id, status)
- Full-Text Search: PostgreSQL tsvector 또는 Elasticsearch

작성 필요: 검색 엔진 선택 (PostgreSQL FTS vs Elasticsearch)


6. 마이그레이션 파일 예시 (V1)

-- V1__create_users.sql
CREATE TABLE users (
    id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    email       VARCHAR(255) NOT NULL UNIQUE,
    name        VARCHAR(100) NOT NULL,
    password_hash VARCHAR(255),
    avatar_url  VARCHAR(500),
    created_at  TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at  TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    deleted_at  TIMESTAMPTZ
);
 
CREATE INDEX idx_users_email ON users(email);

연관 메일