当前位置: 首页 > news >正文

Mysql-定时删除数据库中的验证码

Moudle 1 使用调度器+定时删除事件

数据库实现验证码自动删除的解决方案

-- 删除旧事件(如果存在)
DROP EVENT IF EXISTS delete_expired_captchas;-- 创建新事件(每分钟执行一次)
CREATE EVENT delete_expired_captchas
ON SCHEDULE EVERY 1 MINUTE
STARTS CURRENT_TIMESTAMP
COMMENT '每分钟清理过期验证码'
DO
DELETE FROM captcha 
WHERE created_at < NOW() - INTERVAL 10 MINUTE;

1. 核心思路

数据库本身没有直接的「自动删除过期数据」的功能,但可以通过以下两种方式模拟实现:

  • 数据库事件调度器(如MySQL的Event Scheduler):定期执行删除过期数据的SQL语句。
  • 应用层逻辑:在验证时检查时间差,并在发现过期时删除记录(被动删除)。

2. 具体实现方法

方法一:使用数据库事件调度器(以MySQL为例)
步骤 1:启用事件调度器

默认情况下,MySQL的事件调度器是关闭的。需在配置文件中启用:

-- 检查事件调度器状态
SHOW VARIABLES LIKE 'event_scheduler';-- 启用事件调度器(临时生效)
SET GLOBAL event_scheduler = ON;-- 永久生效需修改配置文件 my.cnf:
[mysqld]
event_scheduler = ON
步骤 2:创建定时删除事件

创建一个每天自动清理过期验证码的事件:

CREATE EVENT delete_expired_captchas
ON SCHEDULE EVERY 1 DAY
STARTS CURRENT_TIMESTAMP
DO
DELETE FROM captcha 
WHERE created_at < NOW() - INTERVAL 10 MINUTE;
步骤 3:验证事件执行
-- 查看事件状态
SHOW EVENTS;-- 手动触发事件(测试用)
CALL delete_expired_captchas;
优缺点
  • 优点:完全由数据库管理,无需应用层干预。
  • 缺点
    • 删除操作是周期性的(如每天一次),不能实时删除过期数据。
    • 高频清理可能影响数据库性能。

方法二:应用层逻辑删除(被动删除)

在验证验证码时,检查时间差并删除过期记录:

@Service
public class DatabaseCaptchaService {@Autowiredprivate JdbcTemplate jdbcTemplate;public boolean validateCaptcha(String key, String userInput) {// 查询验证码及生成时间String sql = "SELECT code, created_at FROM captcha WHERE id = ?";return jdbcTemplate.query(sql, (rs) -> {if (rs.next()) {String storedCode = rs.getString("code");Timestamp createdAt = rs.getTimestamp("created_at");long age = System.currentTimeMillis() - createdAt.getTime();if (age > 10 * 60 * 1000) { // 超过10分钟// 删除过期记录jdbcTemplate.update("DELETE FROM captcha WHERE id = ?", key);return false;}return storedCode.equals(userInput);}return false;}, key);}
}
优缺点
  • 优点:实时删除过期数据,无需额外配置数据库事件。
  • 缺点
    • 依赖业务逻辑触发删除操作,可能遗留未验证的过期数据。
    • 需要手动调用删除逻辑。

3. 完整方案推荐

结合两种方式实现高可靠性:

  1. 应用层逻辑删除:在验证时主动清理过期验证码。
  2. 数据库事件调度器:每日清理残留的过期数据(兜底)。

4. 其他数据库的支持情况

  • PostgreSQL:通过pg_cron扩展或定时任务工具(如cron)实现类似功能。
  • SQL Server:使用SQL Server Agent创建定时作业。
  • SQLite:无内置事件调度器,需依赖应用层逻辑删除。

5. 对比Redis方案

特性

数据库方案

Redis方案

自动删除

需配置事件调度器或应用层逻辑

内置TTL,自动删除

实时性

依赖清理频率(非实时)

实时删除

性能

高频清理可能影响性能

高性能,无额外开销

适用场景

无Redis环境或低频验证码场景

高并发、实时性要求高的场景


6. 最终结论

可以通过数据库实现验证码的自动删除,但需权衡实时性和性能。

  • 推荐方案:优先使用Redis(简单高效),若无Redis则使用数据库事件调度器+应用层逻辑删除的组合方案。

关键代码示例

-- 创建每日清理事件(MySQL)
CREATE EVENT delete_expired_captchas
ON SCHEDULE EVERY 1 DAY
DO
DELETE FROM captcha 
WHERE created_at < NOW() - INTERVAL 10 MINUTE;

Moudle 2 问题解决

-- 创建一个每天自动清理过期验证码的事件: CREATE EVENT delete_expired_captchas ON SCHEDULE EVERY 1 DAY STARTS CURRENT_TIMESTAMP DO DELETE FROM captcha WHERE created_at < NOW() - INTERVAL 10 MINUTE;10分钟没生效。原因排查

解决方案:调整事件调度器设置以自动清理过期验证码

以下是分步说明,确保事件每天自动执行并持续生效:


1. 确认MySQL事件调度器已启用

执行以下SQL命令检查事件调度器状态:

SHOW VARIABLES LIKE 'event_scheduler';

如果结果为 OFF,需启用调度器:

  • SET GLOBAL event_scheduler = ON; -- 临时生效

永久生效需修改MySQL配置文件(如 my.cnf/my.ini):

  • ini
[mysqld]
event_scheduler = ON

修改后重启MySQL服务。


2. 修正事件调度时间间隔

原事件设置为每天执行一次(EVERY 1 DAY),但过期验证码需在生成10分钟后删除,因此需提高执行频率。
推荐方案:每分钟执行一次(实时清理):

-- 删除旧事件(如果存在)
DROP EVENT IF EXISTS delete_expired_captchas;-- 创建新事件(每分钟执行一次)
CREATE EVENT delete_expired_captchas
ON SCHEDULE EVERY 1 MINUTE
STARTS CURRENT_TIMESTAMP
COMMENT '每分钟清理过期验证码'
DO
DELETE FROM captcha 
WHERE created_at < NOW() - INTERVAL 10 MINUTE;

3. 验证事件状态

查看事件列表

  1. SHOW EVENTS FROM your_database_name; -- 替换为实际数据库名
    • 确保事件状态为 ENABLED

手动触发测试

  1. CALL delete_expired_captchas;
    • 检查表中数据是否被删除。

4. 检查权限和语法

权限要求:用户需具备 EVENT 权限。授权命令:

  • GRANT EVENT ON your_database.* TO 'your_user'@'localhost';
  • 语法检查:确保SQL语句无拼写错误(如表名、字段名正确)。

5. 处理时区问题

如果数据库时区与系统时区不一致,可能导致时间计算错误。

查看当前时区

  • SELECT @@global.time_zone, @@session.time_zone;

设置时区(例如设为东八区):

SET GLOBAL time_zone = '+8:00';
SET time_zone = '+8:00';

6. 监控事件执行日志

查看MySQL错误日志(路径通常在 /var/log/mysql/error.log):

  • tail -f /var/log/mysql/error.log
  • 日志中若出现 Event Scheduler 相关记录,表示事件正在运行。

7. 最终效果验证

插入测试数据

INSERT INTO captcha (id, code, created_at)
VALUES ('test', '123456', NOW() - INTERVAL 11 MINUTE);

等待1分钟后检查数据

  1. SELECT * FROM captcha WHERE id = 'test';
  • 数据应被自动删除。

总结

通过以上步骤,事件将每分钟执行一次,确保所有超过10分钟的验证码被实时清理。
关键点:

  • 事件调度器必须启用。
  • 执行频率需足够高(推荐每分钟一次)。
  • 权限、时区、语法需正确配置。
http://www.lqws.cn/news/214741.html

相关文章:

  • 理论物理与高等数学的交叉点“规范场”和“纤维丛”
  • 程序代码篇---Python串口
  • 【题解-洛谷】P10448 组合型枚举
  • Cloudflare 免费域名邮箱 支持 Catch-all 无限别名收件
  • A Execllent Software Project Review and Solutions
  • C++课设:实现简易文件加密工具(凯撒密码、异或加密、Base64编码)
  • day24 元组和OS模块
  • 【STM32F1标准库】理论——定时器中的输出比较
  • 线程池封装
  • 【深度学习-Day 24】过拟合与欠拟合:深入解析模型泛化能力的核心挑战
  • PLC有脉冲输出,但伺服电机无法旋转
  • 移动应用开发专业核心课程以及就业方向
  • 算法-多条件排序
  • STM32学习笔记:定时器(TIM)原理与应用(详解篇)
  • Windows 下搭建 Zephyr 开发环境
  • VirtualBox启动失败@Ubuntu22.04 说是配置文件有问题
  • ubuuntu24.04 编译安装 PostgreSQL15.6+postgis 3.4.2 + pgrouting 3.6.0 +lz4
  • Oracle 客户端深度指南:SQL Developer 与 PL/SQL Developer 全面安装使用教程
  • SQL慢可能是触发了ring buffer
  • 《探秘跨网段局域网IP广播:解锁网络通信的新姿势》
  • Tableau for mac 驱动
  • element树结构el-tree,默认选中当前setCurrentKey无效
  • 从标准输入直接执行 ELF 二进制文件的实用程序解析(C/C++实现)
  • 【LeetCode】3170. 删除星号以后字典序最小的字符串(贪心 | 优先队列)
  • 电脑悬浮窗便签怎么实现四象限玩法?
  • 黄柏基因组-小檗碱生物合成的趋同进化-文献精读142
  • 1.认识Spring
  • 安卓基础(编译.Class)
  • python的numpy的MKL加速
  • 绘制饼图详细过程