-- 文件存储分层改造:yz_system_files 新增归属与存储字段 -- 对应计划文档:go/docs/文件存储分层改造计划.md S1 -- -- 幂等脚本:用存储过程逐项判断,已存在的列/索引自动跳过,可反复执行,不会报 -- 1060 Duplicate column / 1061 Duplicate key。 -- -- 背景:md5 在部分历史库中是 TEXT 类型,MySQL 不允许对 TEXT/BLOB 建整列索引, -- 因此 idx_file_dedup 使用前缀长度 md5(32)(MD5 十六进制串固定 32 字符,等价全值)。 DROP PROCEDURE IF EXISTS `yz_alter_system_files_storage`; DELIMITER $$ CREATE PROCEDURE `yz_alter_system_files_storage`() BEGIN DECLARE v_db VARCHAR(64); SET v_db = DATABASE(); -- 1. 字段:source IF NOT EXISTS ( SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = v_db AND TABLE_NAME = 'yz_system_files' AND COLUMN_NAME = 'source' ) THEN ALTER TABLE `yz_system_files` ADD COLUMN `source` varchar(16) NOT NULL DEFAULT 'backend' COMMENT '来源端: backend-租户后台 platform-平台端'; END IF; -- 2. 字段:scope IF NOT EXISTS ( SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = v_db AND TABLE_NAME = 'yz_system_files' AND COLUMN_NAME = 'scope' ) THEN ALTER TABLE `yz_system_files` ADD COLUMN `scope` varchar(16) NOT NULL DEFAULT 'tenant' COMMENT '归属: tenant-租户共享 user-用户个人'; END IF; -- 3. 字段:storage IF NOT EXISTS ( SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = v_db AND TABLE_NAME = 'yz_system_files' AND COLUMN_NAME = 'storage' ) THEN ALTER TABLE `yz_system_files` ADD COLUMN `storage` varchar(16) NOT NULL DEFAULT '' COMMENT '存储类型: local/qiniu(冗余,便于迁移与排查)'; END IF; -- 4. 字段:object_key IF NOT EXISTS ( SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = v_db AND TABLE_NAME = 'yz_system_files' AND COLUMN_NAME = 'object_key' ) THEN ALTER TABLE `yz_system_files` ADD COLUMN `object_key` varchar(512) NOT NULL DEFAULT '' COMMENT '存储相对路径(不含域名),用于迁移与精确删除'; END IF; -- 5. 索引:查重(source + scope + tid + tuid + md5 前缀) -- 不加 UNIQUE:软删(delete_time)与并发上传下唯一索引会直接报错,去重在代码层完成 IF NOT EXISTS ( SELECT 1 FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = v_db AND TABLE_NAME = 'yz_system_files' AND INDEX_NAME = 'idx_file_dedup' ) THEN ALTER TABLE `yz_system_files` ADD KEY `idx_file_dedup` (`source`, `scope`, `tid`, `tuid`, `md5`(32)); END IF; -- 6. 索引:归属列表过滤 IF NOT EXISTS ( SELECT 1 FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = v_db AND TABLE_NAME = 'yz_system_files' AND INDEX_NAME = 'idx_file_owner' ) THEN ALTER TABLE `yz_system_files` ADD KEY `idx_file_owner` (`source`, `tid`, `scope`, `tuid`, `delete_time`); END IF; END$$ DELIMITER ; CALL `yz_alter_system_files_storage`(); DROP PROCEDURE IF EXISTS `yz_alter_system_files_storage`; -- 7. 老数据初始化:迁移脚本执行前先打底,避免 source/scope 为空导致查询遗漏 UPDATE `yz_system_files` SET `source` = 'backend' WHERE `source` = '' OR `source` IS NULL; UPDATE `yz_system_files` SET `scope` = 'tenant' WHERE `scope` = '' OR `scope` IS NULL; -- 8. 校验(应看到 4 个字段 + 2 个索引) -- SHOW COLUMNS FROM yz_system_files LIKE 'source'; -- SHOW COLUMNS FROM yz_system_files LIKE 'scope'; -- SHOW COLUMNS FROM yz_system_files LIKE 'storage'; -- SHOW COLUMNS FROM yz_system_files LIKE 'object_key'; -- SHOW INDEX FROM yz_system_files WHERE Key_name IN ('idx_file_dedup','idx_file_owner');