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:
parent
c63cf950eb
commit
860293b2b9
@ -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();
|
||||||
|
|
||||||
|
|
||||||
-- ============================================
|
-- ============================================
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user