-- ============================================================================= -- migration_drop_leak.sql - 기존 누수(v2605) 설치 → SHT30 온습도 전용 전환 -- -- ⚠️ 비가역(DROP COLUMN/TABLE) 변경입니다. 반드시 DB 전체 백업 후 실행하세요. -- 운영 데이터(과거 누수 이벤트/사진/사고 이력)가 삭제됩니다. -- -- 이미 v2605 스키마(sensor_log/sensor_status/sensor_metric/sms_log + leak_*)가 -- 적용된 운영 DB를 SHT30 전용으로 정리합니다. 측정 이력(sensor_metric)과 SMS -- 이력(sms_log)은 보존합니다. -- -- 신규 설치라면 이 파일이 아니라 sql/schema_sht30.sql 하나만 실행하세요. -- ============================================================================= SET NAMES utf8mb4; -- 0) sensor_metric 이 없던 구버전 대비: 없으면 생성(있으면 무시). CREATE TABLE IF NOT EXISTS `sensor_metric` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `device_id` VARCHAR(64) NOT NULL DEFAULT '', `device_location` VARCHAR(100) NOT NULL DEFAULT '', `sensor_id` TINYINT UNSIGNED NOT NULL, `sensor_name` VARCHAR(100) NOT NULL DEFAULT '', `metric_type` VARCHAR(30) NOT NULL DEFAULT 'sht30', `temperature_c` DECIMAL(6,2) NULL, `humidity_percent` DECIMAL(5,2) NULL, `metric_status` VARCHAR(30) NOT NULL DEFAULT 'normal', `measured_at` DATETIME NOT NULL, `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), INDEX `idx_sensor_measured` (`sensor_id`, `measured_at`), INDEX `idx_device_sensor` (`device_id`, `sensor_id`), INDEX `idx_metric_type` (`metric_type`, `created_at`), INDEX `idx_status_measured` (`metric_status`, `measured_at`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- 1) 누수 전용 테이블 제거 DROP TABLE IF EXISTS `leak_photo`; DROP TABLE IF EXISTS `leak_incident`; -- 2) sensor_log: 누수 enum 값 정리 → event_type 재정의 (둘 다 멱등) -- (leak_alert/leak_recovery 행이 있으면 periodic 으로 강등 후 enum 축소. -- 이미 정리된 DB면 매칭 행이 없어 no-op, MODIFY 도 동일 enum 재적용이라 안전.) UPDATE `sensor_log` SET `event_type` = 'periodic' WHERE `event_type` IN ('leak_alert', 'leak_recovery'); ALTER TABLE `sensor_log` MODIFY `event_type` ENUM('startup','periodic') NOT NULL DEFAULT 'periodic'; -- 3~4) 인덱스/컬럼 제거·추가는 "존재할 때만" 수행하여 재실행해도 오류가 없게 한다. -- (MySQL/MariaDB 는 DROP COLUMN/INDEX 에 IF EXISTS 호환이 일정치 않으므로 -- information_schema 로 가드하는 멱등 프로시저를 사용한다.) DROP PROCEDURE IF EXISTS _mig_drop_leak; DELIMITER // CREATE PROCEDURE _mig_drop_leak() BEGIN DECLARE db VARCHAR(64); SELECT DATABASE() INTO db; -- sensor_log: is_leak 인덱스/컬럼 제거, event_type 인덱스 추가 IF EXISTS (SELECT 1 FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = db AND TABLE_NAME = 'sensor_log' AND INDEX_NAME = 'idx_is_leak') THEN ALTER TABLE `sensor_log` DROP INDEX `idx_is_leak`; END IF; IF EXISTS (SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = db AND TABLE_NAME = 'sensor_log' AND COLUMN_NAME = 'is_leak') THEN ALTER TABLE `sensor_log` DROP COLUMN `is_leak`; END IF; IF NOT EXISTS (SELECT 1 FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = db AND TABLE_NAME = 'sensor_log' AND INDEX_NAME = 'idx_event_type') THEN ALTER TABLE `sensor_log` ADD INDEX `idx_event_type` (`event_type`, `created_at`); END IF; -- sensor_status: 누수 컬럼/인덱스 제거 (offline_alerted 는 오프라인 SMS에 필요 → 유지) IF EXISTS (SELECT 1 FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = db AND TABLE_NAME = 'sensor_status' AND INDEX_NAME = 'idx_is_leak') THEN ALTER TABLE `sensor_status` DROP INDEX `idx_is_leak`; END IF; IF EXISTS (SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = db AND TABLE_NAME = 'sensor_status' AND COLUMN_NAME = 'is_leak') THEN ALTER TABLE `sensor_status` DROP COLUMN `is_leak`; END IF; IF EXISTS (SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = db AND TABLE_NAME = 'sensor_status' AND COLUMN_NAME = 'leak_periodic_count') THEN ALTER TABLE `sensor_status` DROP COLUMN `leak_periodic_count`; END IF; -- sensor_metric: 임계 경보 조회용 인덱스 추가(없을 때만) IF NOT EXISTS (SELECT 1 FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = db AND TABLE_NAME = 'sensor_metric' AND INDEX_NAME = 'idx_status_measured') THEN ALTER TABLE `sensor_metric` ADD INDEX `idx_status_measured` (`metric_status`, `measured_at`); END IF; END // DELIMITER ; CALL _mig_drop_leak(); DROP PROCEDURE IF EXISTS _mig_drop_leak;