MySQL定时清理订阅制登录系统的过期Premium数据
解决方案:MySQL订阅记录自动清理 + Cron定时任务
嘿,这个需求太常见了,我来一步步帮你落地——不管是当前的1天订阅清理,还是后续扩展到周/月订阅都能完美覆盖。
一、核心SQL删除语句
首先得确认你的用户表结构,假设表名为users,包含两个关键字段:
premium:存储订阅类型(比如'1 DAY'、'1 WEEK')subscription_start:记录用户开通订阅的时间(DATETIME类型)
针对'1 DAY'的专属清理SQL
如果只需要清理1天到期的记录,直接用这条精准语句:
DELETE FROM users WHERE premium = '1 DAY' AND subscription_start + INTERVAL 1 DAY < NOW();
通用版:支持多订阅类型的统一清理SQL
后续要处理'1 WEEK'、'1 MONTH'等类型时,不用写多条重复SQL,用CASE语句统一处理更高效,后续加新类型只需要补充分支即可:
DELETE FROM users WHERE CASE premium WHEN '1 DAY' THEN subscription_start + INTERVAL 1 DAY < NOW() WHEN '1 WEEK' THEN subscription_start + INTERVAL 1 WEEK < NOW() WHEN '1 MONTH' THEN subscription_start + INTERVAL 1 MONTH < NOW() -- 以后加'3 MONTH'、'1 YEAR'直接在这里追加 ELSE FALSE END;
小提示:如果你的表已经有
expiry_time(订阅到期时间)字段,那SQL会更简单——直接判断expiry_time < NOW()就行,比计算时间间隔更准确,建议优先用这种方式。
二、配置每日Cron定时任务
接下来把上面的SQL做成自动执行的定时任务,步骤如下:
1. 安全配置MySQL登录信息
绝对不要在Cron里明文写密码,创建~/.my.cnf文件(记得把权限设为600,防止其他用户读取):
[client] user=你的MySQL用户名 password=你的MySQL密码 database=你的数据库名
2. 编写Cron表达式
推荐每天凌晨2点执行清理(这个时间点系统负载最低),Cron命令如下:
# 单类型清理的Cron(仅针对1天订阅) 0 2 * * * mysql -e "DELETE FROM users WHERE premium = '1 DAY' AND subscription_start + INTERVAL 1 DAY < NOW();" >> /var/log/subscription_cleanup.log 2>&1 # 多类型通用清理的Cron(推荐用这个,后续不用改Cron) 0 2 * * * mysql -e "DELETE FROM users WHERE CASE premium WHEN '1 DAY' THEN subscription_start + INTERVAL 1 DAY < NOW() WHEN '1 WEEK' THEN subscription_start + INTERVAL 1 WEEK < NOW() WHEN '1 MONTH' THEN subscription_start + INTERVAL 1 MONTH < NOW() ELSE FALSE END;" >> /var/log/subscription_cleanup.log 2>&1
3. 验证Cron任务
- 用
crontab -e编辑Cron,粘贴上面的命令 - 重启Cron服务(比如
systemctl restart cron,根据你的操作系统调整) - 可以手动执行一次命令,查看日志
/var/log/subscription_cleanup.log是否正常,同时检查数据库记录是否被正确删除
三、最佳实践建议
- 先查询再删除:执行DELETE前,先跑对应的SELECT语句确认要删除的记录,避免误删:
SELECT * FROM users WHERE premium = '1 DAY' AND subscription_start + INTERVAL 1 DAY < NOW(); - 添加联合索引:给
premium和subscription_start加联合索引,大幅提升查询效率:CREATE INDEX idx_premium_start ON users(premium, subscription_start); - 数据归档:如果需要保留历史记录,建议先把到期记录插入到归档表,再删除原表记录,避免数据丢失。
- 事务保障:如果涉及多表操作,用事务包裹确保原子性;单条DELETE语句本身是原子的,无需额外处理。
内容的提问来源于stack exchange,提问作者swiro9
相关产品推荐
相关产品推荐

