Event Service DDL 최적화 작업 (Medium/Low 우선순위)

Medium 우선순위 수정:
1. created_at, updated_at 기본값 정책 정리
   - DEFAULT CURRENT_TIMESTAMP 제거
   - JPA @CreatedDate/@LastModifiedDate로 관리 명시
   - 주석으로 관리 주체 명확화

2. updated_at Trigger 비활성화
   - JPA 환경에서는 애플리케이션 레벨 관리
   - Trigger 코드는 주석으로 보존 (필요시 활성화 가능)
   - 이중 업데이트 메커니즘 제거로 성능 개선

Low 우선순위 추가:
3. 복합 인덱스 추가 (쿼리 성능 최적화)
   - events: (user_id, status, created_at DESC)
     → 사용자별 상태 필터링 + 최신순 정렬 최적화
   - generated_images: (event_id, is_selected)
     → 이벤트별 선택 이미지 조회 최적화
   - ai_recommendations: (event_id, is_selected)
     → 이벤트별 선택 추천 조회 최적화
   - jobs: (status, created_at DESC)
     → 상태별 최신 작업 조회 최적화

영향:
- JPA와 Database 역할 분담 명확화
- 불필요한 중복 메커니즘 제거
- 쿼리 성능 향상 (복합 인덱스)
- 유지보수성 개선

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
merrycoral 2025-10-24 13:25:31 +09:00
parent c63cf950eb
commit 860293b2b9

View File

@ -30,8 +30,8 @@ CREATE TABLE IF NOT EXISTS events (
status VARCHAR(20) NOT NULL DEFAULT 'DRAFT', status VARCHAR(20) NOT NULL DEFAULT 'DRAFT',
selected_image_id UUID, selected_image_id UUID,
selected_image_url VARCHAR(500), selected_image_url VARCHAR(500),
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, created_at TIMESTAMP NOT NULL, -- Managed by JPA @CreatedDate
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NOT NULL, -- Managed by JPA @LastModifiedDate
-- 제약조건 -- 제약조건
CONSTRAINT chk_event_period CHECK (start_date IS NULL OR end_date IS NULL OR start_date <= end_date), CONSTRAINT chk_event_period CHECK (start_date IS NULL OR end_date IS NULL OR start_date <= end_date),
@ -44,6 +44,9 @@ CREATE INDEX idx_events_store_id ON events(store_id);
CREATE INDEX idx_events_status ON events(status); CREATE INDEX idx_events_status ON events(status);
CREATE INDEX idx_events_created_at ON events(created_at); CREATE INDEX idx_events_created_at ON events(created_at);
-- 복합 인덱스 (쿼리 성능 최적화)
CREATE INDEX idx_events_user_status_created ON events(user_id, status, created_at DESC);
-- 주석 -- 주석
COMMENT ON TABLE events IS '이벤트 마스터 테이블'; COMMENT ON TABLE events IS '이벤트 마스터 테이블';
COMMENT ON COLUMN events.event_id IS '이벤트 ID (PK)'; COMMENT ON COLUMN events.event_id IS '이벤트 ID (PK)';
@ -101,8 +104,8 @@ CREATE TABLE IF NOT EXISTS generated_images (
style VARCHAR(50), style VARCHAR(50),
platform VARCHAR(50), platform VARCHAR(50),
is_selected BOOLEAN NOT NULL DEFAULT FALSE, is_selected BOOLEAN NOT NULL DEFAULT FALSE,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, created_at TIMESTAMP NOT NULL, -- Managed by JPA @CreatedDate
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NOT NULL, -- Managed by JPA @LastModifiedDate
-- 제약조건 -- 제약조건
CONSTRAINT fk_generated_images_event FOREIGN KEY (event_id) CONSTRAINT fk_generated_images_event FOREIGN KEY (event_id)
@ -113,6 +116,9 @@ CREATE TABLE IF NOT EXISTS generated_images (
CREATE INDEX idx_generated_images_event_id ON generated_images(event_id); CREATE INDEX idx_generated_images_event_id ON generated_images(event_id);
CREATE INDEX idx_generated_images_is_selected ON generated_images(is_selected); CREATE INDEX idx_generated_images_is_selected ON generated_images(is_selected);
-- 복합 인덱스 (이벤트별 선택 이미지 조회 최적화)
CREATE INDEX idx_generated_images_event_selected ON generated_images(event_id, is_selected);
-- 주석 -- 주석
COMMENT ON TABLE generated_images IS '생성된 이미지 테이블'; COMMENT ON TABLE generated_images IS '생성된 이미지 테이블';
COMMENT ON COLUMN generated_images.image_id IS '이미지 ID (PK)'; COMMENT ON COLUMN generated_images.image_id IS '이미지 ID (PK)';
@ -140,8 +146,8 @@ CREATE TABLE IF NOT EXISTS ai_recommendations (
promotion_type VARCHAR(50), promotion_type VARCHAR(50),
target_audience VARCHAR(100), target_audience VARCHAR(100),
is_selected BOOLEAN NOT NULL DEFAULT FALSE, is_selected BOOLEAN NOT NULL DEFAULT FALSE,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, created_at TIMESTAMP NOT NULL, -- Managed by JPA @CreatedDate
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NOT NULL, -- Managed by JPA @LastModifiedDate
-- 제약조건 -- 제약조건
CONSTRAINT fk_ai_recommendations_event FOREIGN KEY (event_id) CONSTRAINT fk_ai_recommendations_event FOREIGN KEY (event_id)
@ -152,6 +158,9 @@ CREATE TABLE IF NOT EXISTS ai_recommendations (
CREATE INDEX idx_ai_recommendations_event_id ON ai_recommendations(event_id); CREATE INDEX idx_ai_recommendations_event_id ON ai_recommendations(event_id);
CREATE INDEX idx_ai_recommendations_is_selected ON ai_recommendations(is_selected); CREATE INDEX idx_ai_recommendations_is_selected ON ai_recommendations(is_selected);
-- 복합 인덱스 (이벤트별 선택 추천 조회 최적화)
CREATE INDEX idx_ai_recommendations_event_selected ON ai_recommendations(event_id, is_selected);
-- 주석 -- 주석
COMMENT ON TABLE ai_recommendations IS 'AI 추천 이벤트 기획안 테이블'; COMMENT ON TABLE ai_recommendations IS 'AI 추천 이벤트 기획안 테이블';
COMMENT ON COLUMN ai_recommendations.recommendation_id IS '추천 ID (PK)'; COMMENT ON COLUMN ai_recommendations.recommendation_id IS '추천 ID (PK)';
@ -181,8 +190,8 @@ CREATE TABLE IF NOT EXISTS jobs (
result_key VARCHAR(200), result_key VARCHAR(200),
error_message VARCHAR(500), error_message VARCHAR(500),
completed_at TIMESTAMP, completed_at TIMESTAMP,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, created_at TIMESTAMP NOT NULL, -- Managed by JPA @CreatedDate
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NOT NULL, -- Managed by JPA @LastModifiedDate
-- 제약조건 -- 제약조건
CONSTRAINT fk_jobs_event FOREIGN KEY (event_id) CONSTRAINT fk_jobs_event FOREIGN KEY (event_id)
@ -197,6 +206,9 @@ CREATE INDEX idx_jobs_event_id ON jobs(event_id);
CREATE INDEX idx_jobs_status ON jobs(status); CREATE INDEX idx_jobs_status ON jobs(status);
CREATE INDEX idx_jobs_created_at ON jobs(created_at); CREATE INDEX idx_jobs_created_at ON jobs(created_at);
-- 복합 인덱스 (상태별 최신 작업 조회 최적화)
CREATE INDEX idx_jobs_status_created ON jobs(status, created_at DESC);
-- 주석 -- 주석
COMMENT ON TABLE jobs IS '비동기 작업 테이블'; COMMENT ON TABLE jobs IS '비동기 작업 테이블';
COMMENT ON COLUMN jobs.job_id IS '작업 ID (PK)'; COMMENT ON COLUMN jobs.job_id IS '작업 ID (PK)';
@ -214,31 +226,37 @@ COMMENT ON COLUMN jobs.updated_at IS '수정일시';
-- ============================================ -- ============================================
-- Trigger for updated_at (자동 업데이트) -- Trigger for updated_at (자동 업데이트)
-- ============================================ -- ============================================
-- NOTE: updated_at 필드는 JPA @LastModifiedDate 어노테이션으로 관리됩니다.
-- 따라서 PostgreSQL Trigger는 사용하지 않습니다.
-- JPA 환경에서는 애플리케이션 레벨에서 자동으로 updated_at이 갱신됩니다.
--
-- 만약 JPA 외부에서 직접 SQL로 데이터를 수정하는 경우,
-- 아래 Trigger를 활성화할 수 있습니다.
-- updated_at 자동 업데이트 함수 -- updated_at 자동 업데이트 함수 (비활성화)
CREATE OR REPLACE FUNCTION update_updated_at_column() -- CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$ -- RETURNS TRIGGER AS $$
BEGIN -- BEGIN
NEW.updated_at = CURRENT_TIMESTAMP; -- NEW.updated_at = CURRENT_TIMESTAMP;
RETURN NEW; -- RETURN NEW;
END; -- END;
$$ language 'plpgsql'; -- $$ language 'plpgsql';
-- events 테이블 트리거 -- events 테이블 트리거 (비활성화)
CREATE TRIGGER update_events_updated_at BEFORE UPDATE ON events -- CREATE TRIGGER update_events_updated_at BEFORE UPDATE ON events
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); -- FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
-- generated_images 테이블 트리거 -- generated_images 테이블 트리거 (비활성화)
CREATE TRIGGER update_generated_images_updated_at BEFORE UPDATE ON generated_images -- CREATE TRIGGER update_generated_images_updated_at BEFORE UPDATE ON generated_images
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); -- FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
-- ai_recommendations 테이블 트리거 -- ai_recommendations 테이블 트리거 (비활성화)
CREATE TRIGGER update_ai_recommendations_updated_at BEFORE UPDATE ON ai_recommendations -- CREATE TRIGGER update_ai_recommendations_updated_at BEFORE UPDATE ON ai_recommendations
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); -- FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
-- jobs 테이블 트리거 -- jobs 테이블 트리거 (비활성화)
CREATE TRIGGER update_jobs_updated_at BEFORE UPDATE ON jobs -- CREATE TRIGGER update_jobs_updated_at BEFORE UPDATE ON jobs
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); -- FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
-- ============================================ -- ============================================