12.26

  1. 窗口函数ROW_NUMBER去重删除(MySQL 8.0+,精准保留目标行)

sql

-- 按name分组,保留每组最小id,删其余重复行
DELETE t FROM user t
JOIN (
SELECT id, ROW_NUMBER() OVER (PARTITION BY name ORDER BY id) rn
FROM user
) temp ON t.id = temp.id
WHERE temp.rn > 1;

  • 窗口函数分组排序,比JOIN写法更清晰,适合复杂分组去重。
  1. 触发器辅助的标记删除(逻辑删,保留数据可恢复)

sql

-- 先建触发器,删除时写入删除日志
DELIMITER //
CREATE TRIGGER trg_user_delete BEFORE DELETE ON user
FOR EACH ROW
BEGIN
INSERT INTO user_delete_log(id, name, delete_time)
VALUES(OLD.id, OLD.name, NOW());
END //
DELIMITER ;

-- 执行删除(触发日志记录,实现逻辑删+可追溯)
DELETE FROM user WHERE id = 2002;

  • 适合需保留删除记录、可追溯或恢复的场景,避免物理删丢数据。
  1. 存储过程分批删除(大表防锁表,可控高效)

sql

DELIMITER //
CREATE PROCEDURE batch_delete_large_logs(IN days INT, IN batch_size INT)
BEGIN
REPEAT
DELETE FROM large_logs
WHERE log_time < DATE_SUB(NOW(), INTERVAL days DAY)
LIMIT batch_size;
UNTIL ROW_COUNT() = 0 END REPEAT;
END //
DELIMITER ;

-- 调用:删90天前日志,每次删1000条
CALL batch_delete_large_logs(90, 1000);

  • 大表分批删,避免长事务锁表,降低对业务的影响。
posted @ 2025-12-26 23:57  喜欢写轻小说的日央  阅读(6)  评论(0)    收藏  举报