-- ============================================= -- 清理孤立数据(在添加外键前必须执行) -- 版本: cleanup-script -- 日期: 2026-04-07 -- 说明: 删除所有违反引用完整性的孤立数据 -- ============================================= BEGIN; -- ============================================================ -- 第一部分:清理项目员工表的孤立数据 -- ============================================================ -- 1.1 删除引用不存在项目的员工记录 DELETE FROM project_staff WHERE project_id IS NOT NULL AND project_id NOT IN (SELECT id FROM mdm_project); -- 1.2 删除引用不存在用户的员工记录(理论上不应该存在,因为已有外键) DELETE FROM project_staff WHERE user_id NOT IN (SELECT id FROM auth_user); -- 1.3 删除引用不存在班组长ID的记录(leader_id允许为NULL) UPDATE project_staff SET leader_id = NULL WHERE leader_id IS NOT NULL AND leader_id NOT IN (SELECT id FROM auth_user); -- ============================================================ -- 第二部分:清理房屋表的孤立数据 -- ============================================================ -- 2.1 删除引用不存在项目的房屋记录 DELETE FROM space WHERE project_id NOT IN (SELECT id FROM mdm_project); -- ============================================================ -- 第三部分:清理用户表的可能孤立数据 -- ============================================================ -- 3.1 清理用户表中引用不存在部门的记录(dept_id允许为NULL) DO $$ BEGIN IF EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'auth_user' AND column_name = 'dept_id' ) THEN UPDATE auth_user SET dept_id = NULL WHERE dept_id IS NOT NULL AND dept_id NOT IN (SELECT id FROM dept); END IF; END $$; -- ============================================================ -- 第四部分:清理角色表的可能孤立数据 -- ============================================================ -- 4.1 清理角色表中引用不存在项目的记录(project_id允许为NULL) DO $$ BEGIN IF EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'auth_role' AND column_name = 'project_id' ) THEN UPDATE auth_role SET project_id = NULL WHERE project_id IS NOT NULL AND project_id NOT IN (SELECT id FROM mdm_project); END IF; END $$; -- ============================================================ -- 第五部分:清理用户角色关联表的可能孤立数据 -- ============================================================ -- 5.1 清理用户角色表中引用不存在项目的记录(project_id允许为NULL) DO $$ BEGIN IF EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'auth_user_role' AND column_name = 'project_id' ) THEN UPDATE auth_user_role SET project_id = NULL WHERE project_id IS NOT NULL AND project_id NOT IN (SELECT id FROM mdm_project); END IF; END $$; -- ============================================================ -- 第六部分:统计清理结果(用于验证) -- ============================================================ -- 创建临时表记录清理结果(可选) DROP TABLE IF EXISTS cleanup_statistics; CREATE TEMPORARY TABLE cleanup_statistics ( table_name VARCHAR(50), check_type VARCHAR(100), orphan_count INT, cleaned_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- 插入统计信息 INSERT INTO cleanup_statistics (table_name, check_type, orphan_count) SELECT 'project_staff', 'invalid_project_id', COUNT(*) FROM project_staff WHERE project_id IS NOT NULL AND project_id NOT IN (SELECT id FROM mdm_project); INSERT INTO cleanup_statistics (table_name, check_type, orphan_count) SELECT 'space', 'invalid_project_id', COUNT(*) FROM space WHERE project_id NOT IN (SELECT id FROM mdm_project); -- 输出清理结果 SELECT * FROM cleanup_statistics ORDER BY table_name, check_type; COMMIT; -- ============================================= -- 使用说明: -- -- 1. 在生产环境执行前,请先备份数据库 -- 2. 建议在维护窗口期执行 -- 3. 执行完成后,检查cleanup_statistics确认无孤立数据 -- 4. 确认无误后,再执行 V999__add_foreign_keys.sql -- -- 回滚方案:如果有误删,从备份恢复 -- =============================================