diff --git a/develop/database/sql/event-service-ddl.sql b/develop/database/sql/event-service-ddl.sql index 7081213..0574d58 100644 --- a/develop/database/sql/event-service-ddl.sql +++ b/develop/database/sql/event-service-ddl.sql @@ -30,8 +30,8 @@ CREATE TABLE IF NOT EXISTS events ( status VARCHAR(20) NOT NULL DEFAULT 'DRAFT', selected_image_id UUID, selected_image_url VARCHAR(500), - created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + created_at TIMESTAMP NOT NULL, -- Managed by JPA @CreatedDate + 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), @@ -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_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 COLUMN events.event_id IS '이벤트 ID (PK)'; @@ -101,8 +104,8 @@ CREATE TABLE IF NOT EXISTS generated_images ( style VARCHAR(50), platform VARCHAR(50), is_selected BOOLEAN NOT NULL DEFAULT FALSE, - created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + created_at TIMESTAMP NOT NULL, -- Managed by JPA @CreatedDate + updated_at TIMESTAMP NOT NULL, -- Managed by JPA @LastModifiedDate -- 제약조건 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_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 COLUMN generated_images.image_id IS '이미지 ID (PK)'; @@ -140,8 +146,8 @@ CREATE TABLE IF NOT EXISTS ai_recommendations ( promotion_type VARCHAR(50), target_audience VARCHAR(100), is_selected BOOLEAN NOT NULL DEFAULT FALSE, - created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + created_at TIMESTAMP NOT NULL, -- Managed by JPA @CreatedDate + updated_at TIMESTAMP NOT NULL, -- Managed by JPA @LastModifiedDate -- 제약조건 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_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 COLUMN ai_recommendations.recommendation_id IS '추천 ID (PK)'; @@ -181,8 +190,8 @@ CREATE TABLE IF NOT EXISTS jobs ( result_key VARCHAR(200), error_message VARCHAR(500), completed_at TIMESTAMP, - created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + created_at TIMESTAMP NOT NULL, -- Managed by JPA @CreatedDate + updated_at TIMESTAMP NOT NULL, -- Managed by JPA @LastModifiedDate -- 제약조건 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_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 COLUMN jobs.job_id IS '작업 ID (PK)'; @@ -214,31 +226,37 @@ COMMENT ON COLUMN jobs.updated_at IS '수정일시'; -- ============================================ -- Trigger for updated_at (자동 업데이트) -- ============================================ +-- NOTE: updated_at 필드는 JPA @LastModifiedDate 어노테이션으로 관리됩니다. +-- 따라서 PostgreSQL Trigger는 사용하지 않습니다. +-- JPA 환경에서는 애플리케이션 레벨에서 자동으로 updated_at이 갱신됩니다. +-- +-- 만약 JPA 외부에서 직접 SQL로 데이터를 수정하는 경우, +-- 아래 Trigger를 활성화할 수 있습니다. --- updated_at 자동 업데이트 함수 -CREATE OR REPLACE FUNCTION update_updated_at_column() -RETURNS TRIGGER AS $$ -BEGIN - NEW.updated_at = CURRENT_TIMESTAMP; - RETURN NEW; -END; -$$ language 'plpgsql'; +-- updated_at 자동 업데이트 함수 (비활성화) +-- CREATE OR REPLACE FUNCTION update_updated_at_column() +-- RETURNS TRIGGER AS $$ +-- BEGIN +-- NEW.updated_at = CURRENT_TIMESTAMP; +-- RETURN NEW; +-- END; +-- $$ language 'plpgsql'; --- events 테이블 트리거 -CREATE TRIGGER update_events_updated_at BEFORE UPDATE ON events - FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); +-- events 테이블 트리거 (비활성화) +-- CREATE TRIGGER update_events_updated_at BEFORE UPDATE ON events +-- FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); --- generated_images 테이블 트리거 -CREATE TRIGGER update_generated_images_updated_at BEFORE UPDATE ON generated_images - FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); +-- generated_images 테이블 트리거 (비활성화) +-- CREATE TRIGGER update_generated_images_updated_at BEFORE UPDATE ON generated_images +-- FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); --- ai_recommendations 테이블 트리거 -CREATE TRIGGER update_ai_recommendations_updated_at BEFORE UPDATE ON ai_recommendations - FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); +-- ai_recommendations 테이블 트리거 (비활성화) +-- CREATE TRIGGER update_ai_recommendations_updated_at BEFORE UPDATE ON ai_recommendations +-- FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); --- jobs 테이블 트리거 -CREATE TRIGGER update_jobs_updated_at BEFORE UPDATE ON jobs - FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); +-- jobs 테이블 트리거 (비활성화) +-- CREATE TRIGGER update_jobs_updated_at BEFORE UPDATE ON jobs +-- FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); -- ============================================