guoyu/数据库维护.sql
2025-12-11 23:28:07 +08:00

166 lines
4.8 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- ========================================
-- 数据库维护脚本
-- ========================================
-- 用途:定期清理和优化数据
-- 使用方法mysql -u root -proot study < 数据库维护.sql
USE study;
-- ========================================
-- 1. 数据清理
-- ========================================
-- 1.1 清理孤儿记录(学生已删除但分配记录仍存在)
SELECT '开始清理孤儿记录...' AS step;
SELECT COUNT(*) AS
FROM student_class sc
LEFT JOIN sys_user u ON sc.student_id = u.user_id
WHERE u.user_id IS NULL OR u.del_flag = '2';
-- 执行清理(可选,默认注释掉,需要时取消注释)
-- DELETE sc FROM student_class sc
-- LEFT JOIN sys_user u ON sc.student_id = u.user_id
-- WHERE u.user_id IS NULL OR u.del_flag = '2';
-- SELECT '✓ 孤儿记录已清理' AS result;
-- ========================================
-- 2. 数据一致性修复
-- ========================================
SELECT '开始修复数据一致性...' AS step;
-- 2.1 修复所有正常学员的status为1
UPDATE student_class sc
INNER JOIN sys_user u ON sc.student_id = u.user_id
SET sc.status = 1
WHERE u.del_flag = '0'
AND u.register_type = 'student'
AND sc.status = 0;
SELECT ROW_COUNT() AS ;
SELECT '✓ status修复完成' AS result;
-- ========================================
-- 3. 数据统计
-- ========================================
SELECT '生成统计报告...' AS step;
-- 3.1 总体统计
SELECT
'总体统计' AS ,
COUNT(DISTINCT u.user_id) AS ,
COUNT(DISTINCT sc.class_id) AS ,
COUNT(DISTINCT CASE WHEN sc.status = 1 THEN u.user_id END) AS ,
COUNT(DISTINCT CASE WHEN sc.status = 0 THEN u.user_id END) AS
FROM sys_user u
LEFT JOIN student_class sc ON u.user_id = sc.student_id
WHERE u.del_flag = '0'
AND u.register_type = 'student';
-- 3.2 各监区统计
SELECT
u.prison_area AS ,
COUNT(DISTINCT u.user_id) AS ,
COUNT(DISTINCT sc.class_id) AS ,
COUNT(DISTINCT CASE WHEN sc.status = 1 THEN u.user_id END) AS
FROM sys_user u
LEFT JOIN student_class sc ON u.user_id = sc.student_id AND sc.status = 1
WHERE u.del_flag = '0'
AND u.register_type = 'student'
GROUP BY u.prison_area
ORDER BY u.prison_area;
-- 3.3 班级学生数Top10
SELECT
c.class_name AS ,
COUNT(*) AS ,
GROUP_CONCAT(DISTINCT u.prison_area) AS
FROM class c
INNER JOIN student_class sc ON c.id = sc.class_id
INNER JOIN sys_user u ON sc.student_id = u.user_id
WHERE sc.status = 1
AND u.del_flag = '0'
GROUP BY c.class_name
ORDER BY DESC
LIMIT 10;
-- ========================================
-- 4. 异常数据检测
-- ========================================
SELECT '检测异常数据...' AS step;
-- 4.1 一个学生在多个有效班级
SELECT
u.user_id AS ID,
u.nick_name AS ,
COUNT(*) AS ,
GROUP_CONCAT(c.class_name) AS
FROM sys_user u
INNER JOIN student_class sc ON u.user_id = sc.student_id
INNER JOIN class c ON sc.class_id = c.id
WHERE sc.status = 1
AND u.del_flag = '0'
GROUP BY u.user_id, u.nick_name
HAVING COUNT(*) > 1
LIMIT 20;
-- 4.2 班级存在无效分配的情况
SELECT
c.class_name AS ,
COUNT(*) AS ,
SUM(CASE WHEN sc.status = 1 THEN 1 ELSE 0 END) AS ,
SUM(CASE WHEN sc.status = 0 THEN 1 ELSE 0 END) AS
FROM class c
INNER JOIN student_class sc ON c.id = sc.class_id
INNER JOIN sys_user u ON sc.student_id = u.user_id
WHERE u.del_flag = '0'
GROUP BY c.class_name
HAVING SUM(CASE WHEN sc.status = 0 THEN 1 ELSE 0 END) > 0
ORDER BY DESC
LIMIT 10;
-- ========================================
-- 5. 索引优化建议
-- ========================================
SELECT '检查索引情况...' AS step;
-- 检查student_class表的索引
SHOW INDEX FROM student_class;
-- 建议添加的索引(如果不存在)
-- CREATE INDEX idx_student_status ON student_class(student_id, status);
-- CREATE INDEX idx_class_status ON student_class(class_id, status);
-- ========================================
-- 6. 表空间优化
-- ========================================
SELECT '优化表空间...' AS step;
-- 优化student_class表整理碎片
OPTIMIZE TABLE student_class;
-- 优化sys_user表
OPTIMIZE TABLE sys_user;
SELECT '✓ 表空间优化完成' AS result;
-- ========================================
-- 完成
-- ========================================
SELECT '========================================' AS separator;
SELECT '✅ 数据库维护完成' AS status;
SELECT NOW() AS ;
SELECT '========================================' AS separator;
-- 建议:
-- 1. 每周运行一次此脚本
-- 2. 导入大量数据后运行此脚本
-- 3. 发现数据问题时运行此脚本