如何创建MySQL事件为Users表所有用户每日自动插入mileagesnew记录
MySQL 每日批量为所有用户插入默认里程记录的实现方案
你完全不需要为每个用户单独编写插入语句,借助MySQL原生的批量插入语法+防重约束,就能一步实现稳定的每日自动插入逻辑,具体步骤如下:
1. 先配置表级防重机制(生产必做)
要彻底避免同用户同一天出现多条重复里程记录,首先要给mileagesnew表增加user_id和date的联合唯一索引,从数据库层面拦截重复数据,哪怕事件触发异常重跑也不会产生冗余:
-- 执行前先排查表内是否存在同用户同日期的重复脏数据,避免索引创建失败 ALTER TABLE `mileagesnew` ADD UNIQUE KEY `uk_unique_user_daily_mileage` (`user_id`, `date`);
注:没有这层约束的话,后续遇到数据库重启、事件异常触发等场景,极容易产生重复的无效记录。
2. 替换事件内的核心插入逻辑
把原来写死单值的VALUES固定值写法,替换为从Users表批量查询用户ID的INSERT ... SELECT语法,完整可运行的事件创建代码如下:
-- 先清理同名旧事件,避免创建冲突 DROP EVENT IF EXISTS `Daily_Mileage`; -- 临时修改语句分隔符,兼容事件内的逻辑块 DELIMITER ;; CREATE EVENT `Daily_Mileage` ON SCHEDULE EVERY 1 DAY -- 执行时间:从次日开始,每天凌晨1点跑批 STARTS (TIMESTAMP(CURRENT_DATE) + INTERVAL 1 DAY + INTERVAL 1 HOUR) ON COMPLETION PRESERVE ENABLE -- 事件到期后保留状态,不会自动删除 DO INSERT INTO `mileagesnew` ( `user_id`, `date`, `mileage`, `fuel_mileage`, `fuel`, `fuel_cost`, `km`, `kmpl`, `remarks`, `created_at`, `updated_at` ) -- 直接从Users表取所有用户ID批量插入 SELECT u.`id`, CURRENT_DATE, '0', '0', '0', '0', '0', '0', '', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP FROM `Users` u -- 兜底防重:碰到已存在的同用户同日期记录,直接跳过插入,仅更新时间戳 ON DUPLICATE KEY UPDATE `updated_at` = CURRENT_TIMESTAMP; ;; -- 恢复默认语句分隔符 DELIMITER ;
3. 灵活调整插入范围
如果不需要给所有用户插入记录,可以在上述SELECT语句后加WHERE过滤条件,比如仅给状态为正常启用的用户生成当日里程记录:
-- 示例:仅插入状态为1的启用用户 FROM `Users` u WHERE u.`status` = 1
4. 检查事件调度器状态
如果创建完事件不执行,优先检查MySQL全局的事件调度器是否开启:
-- 查看调度器状态,返回ON即为开启 SHOW VARIABLES LIKE 'event_scheduler';
如果返回值为OFF,可以执行以下命令临时开启(永久生效需要修改MySQL配置文件my.cnf的event_scheduler参数为ON):
SET GLOBAL event_scheduler = ON;
内容的提问来源于stack exchange,提问作者Developer
相关产品推荐
相关产品推荐

