-- ============================================================================= -- social_upload 병합 DDL (수동 실행 전용) -- -- `ssul_social_upload` 를 없애고 castad `social_upload` 가 ADO2 영상과 썰박스 -- 콘텐츠의 업로드 기록을 함께 담는다 — comment / video_reaction 병합과 같은 패턴: -- 대상은 `video_id` 또는 `content_id` 중 **정확히 하나**만 채워지며 CHECK 로 강제. -- -- 병합의 실익: -- - dashboard 통계(`app/dashboard/`)가 SocialUpload 만 읽는데 video_id 를 보지 -- 않으므로, 병합하면 썰박스 업로드도 **자동으로 통계에 잡힌다.** -- - 업로드 서비스·워커·모달을 테이블 분기 없이 재사용한다. -- -- 전제(2026-07-30 확인): ssul_social_upload 0행, social_upload 1행(video_id 채워져 -- 있어 CHECK 를 이미 만족). 이관할 데이터가 없다. -- -- 실행 순서: 2026-07-30-ssulbox.sql 의 §1(ssul_content 생성) 이후. -- 대상: MySQL 8.0.16+ (CHECK 가 실제로 강제되는 버전. 운영은 8.4) -- ============================================================================= -- 1. content_id 추가 + FK. -- upload_seq 채번 인덱스 (content_id, social_account_id, upload_seq) 는 -- 선행 컬럼이 content_id 라 FK 인덱스 요건도 겸한다(단독 인덱스 불필요 — -- video_reaction 때는 유니크가 user_uuid 선행이라 단독이 필요했던 것과 다르다). ALTER TABLE `social_upload` ADD COLUMN `content_id` BIGINT NULL COMMENT '썰박스 콘텐츠 id (ADO2 업로드면 NULL)' AFTER `video_id`, ADD CONSTRAINT `fk_social_upload_content` FOREIGN KEY (`content_id`) REFERENCES `ssul_content` (`id`) ON DELETE CASCADE, ADD INDEX `idx_social_upload_content_seq` (`content_id`, `social_account_id`, `upload_seq`); -- 2. video_id 를 nullable 로. 기존 행은 전부 ADO2 업로드라 값이 있어 영향 없다. ALTER TABLE `social_upload` MODIFY COLUMN `video_id` INT NULL COMMENT 'ADO2 영상 id (썰박스 업로드면 NULL)'; -- 3. "정확히 하나만 채워짐" 강제. 이게 없으면 둘 다 NULL 이거나 둘 다 채워진 -- 행이 조용히 생긴다. ALTER TABLE `social_upload` ADD CONSTRAINT `ck_social_upload_one_target` CHECK ((`video_id` IS NULL) <> (`content_id` IS NULL)); -- 4. 과도기 테이블 제거 (로컬 등 이미 만든 환경만 해당. 운영은 애초에 안 만든다). -- ⚠️ 행이 남아 있으면 social_upload 로 이관한 뒤에 지울 것. -- (2026-07-30 확인 시점에는 0행이라 이관이 필요 없었다) DROP TABLE IF EXISTS `ssul_social_upload`; -- ============================================================================= -- 검증 쿼리 (실행 후 확인용) -- ============================================================================= -- SELECT column_name, column_type, is_nullable FROM information_schema.columns -- WHERE table_schema = DATABASE() AND table_name = 'social_upload' -- AND column_name IN ('video_id','content_id'); -- SELECT constraint_name FROM information_schema.table_constraints -- WHERE table_schema = DATABASE() AND table_name = 'social_upload' -- AND constraint_type = 'CHECK'; -- SELECT COUNT(*) FROM information_schema.tables -- WHERE table_schema = DATABASE() AND table_name = 'ssul_social_upload'; -- 0 기대