Mysql创建每日预聚合表、创建增量更新存储过程、启动事件

Mysql创建每日预聚合表

一、创建每日预聚合表(每日人脸识别统计表)

bash 复制代码
CREATE TABLE IF NOT EXISTS xy_daily_face_stats (
    stat_date DATE PRIMARY KEY COMMENT '统计日期(yyyy-MM-dd)',
    daily_unique_person INT NOT NULL DEFAULT 0 COMMENT '当日去重人数',
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    INDEX idx_daily_count (daily_unique_person)  -- 用于查询排序优化
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='每日刷脸统计表';

二、创建增量更新存储过程

查看所有存储过程

bash 复制代码
SHOW PROCEDURE STATUS WHERE Db = 'zhgddb';

方案A:更新指定日期(灵活模式)

bash 复制代码
CREATE PROCEDURE sp_update_daily_face_stats(IN p_date DATE)
BEGIN
    -- 声明变量
    DECLARE v_daily_unique INT DEFAULT 0;
    -- 计算指定日期的统计数据
    SELECT 
        COUNT(DISTINCT personId)
    INTO 
        v_daily_unique
    FROM xy_importandexport_record
    WHERE eventName = 'acs.acs.eventType.successFace'
      AND inAndOutType = 1
      AND DATE(eventTime) = p_date;
    
    -- 插入或更新统计表(使用 ON DUPLICATE KEY UPDATE)
    INSERT INTO xy_daily_face_stats (stat_date, daily_unique_person)
    VALUES (p_date, v_daily_unique)
    ON DUPLICATE KEY UPDATE 
        daily_unique_person = VALUES(daily_unique_person),
        updated_at = CURRENT_TIMESTAMP;
    
    -- 返回处理结果(可选)
    SELECT CONCAT('Updated: ', p_date, 
                  ', Unique: ', v_daily_unique) AS result;
END
bash 复制代码
-- 1. 查看存储过程
SHOW CREATE PROCEDURE sp_update_daily_face_stats;
-- 3. 执行
CALL sp_update_daily_face_stats('2026-01-01');
-- 4. 验证
SELECT * FROM xy_daily_face_stats ORDER BY stat_date DESC LIMIT 10;

方案B:批量更新指定日期范围(补数据用)

bash 复制代码
CREATE PROCEDURE sp_update_date_range(IN p_start_date DATE, IN p_end_date DATE)
BEGIN
    DECLARE v_current_date DATE;
    DECLARE v_daily_unique INT;
    
    SET v_current_date = p_start_date;
    
    -- 循环处理每一天
    WHILE v_current_date <= p_end_date DO
        -- 计算当天数据
        SELECT 
            COUNT(DISTINCT personId)
        INTO 
            v_daily_unique
        FROM xy_importandexport_record
        WHERE eventName = 'acs.acs.eventType.successFace'
          AND inAndOutType = 1
          AND DATE(eventTime) = v_current_date;
        
        -- 插入或更新
        INSERT INTO xy_daily_face_stats (stat_date, daily_unique_person)
        VALUES (v_current_date, v_daily_unique)
        ON DUPLICATE KEY UPDATE 
            daily_unique_person = VALUES(daily_unique_person),
            updated_at = CURRENT_TIMESTAMP;
        -- 下一天
        SET v_current_date = DATE_ADD(v_current_date, INTERVAL 1 DAY);
    END WHILE;
    
    SELECT CONCAT('Updated from ', p_start_date, ' to ', p_end_date) AS result;
END 
bash 复制代码
-- 1. 查看存储过程
SHOW CREATE PROCEDURE sp_update_date_range;
-- 2. 删除旧存储过程
-- DROP PROCEDURE IF EXISTS sp_update_date_range;
-- 3. 执行
CALL sp_update_date_range('2026-08-06', '2026-08-06');
-- 4. 验证
SELECT * FROM xy_daily_face_stats ORDER BY stat_date DESC LIMIT 10;

三、创建事件调度器(自动执行)

3.1 开启事件调度器

bash 复制代码
-- 检查是否开启
SHOW VARIABLES LIKE 'event_scheduler';

-- 开启(临时生效)
SET GLOBAL event_scheduler = ON;

-- 永久开启(修改配置文件 my.cnf 或 my.ini)
-- 在 [mysqld] 下添加:
-- event_scheduler = ON

3.2 创建每日执行事件

每小时执行 + 只更新当天,第二天凌晨固化(推荐)
bash 复制代码
-- 1. 每小时执行:更新当天数据(实时查询用)
CREATE EVENT evt_hourly_update_today
ON SCHEDULE EVERY 1 HOUR
STARTS CONCAT(CURDATE(), ' 01:00:00')
DO CALL sp_update_daily_face_stats(CURDATE());

-- 2. 每天凌晨2点:执行昨天的数据(固化,用于历史报表)
CREATE EVENT evt_daily_finalize_yesterday
ON SCHEDULE EVERY 1 DAY
STARTS CONCAT(CURDATE() + INTERVAL 1 DAY, ' 02:00:00')
DO CALL sp_update_daily_face_stats(DATE_SUB(CURDATE(), INTERVAL 1 DAY));
bash 复制代码
执行时间线:

08-06 01:00:更新 08-06 00:00-01:00 的数据

08-06 02:00:更新 08-06 00:00-02:00 的数据(覆盖)

08-06 03:00:更新 08-06 00:00-03:00 的数据(覆盖)

...

08-06 23:00:更新 08-06 00:00-23:00 的数据(覆盖)

08-07 00:00:更新 08-06 全天数据(覆盖)

08-07 02:00:固化 08-06 的数据(最终版本)

四、 管理事件

bash 复制代码
-- 查看所有事件
SHOW EVENTS;

-- 启用事件:每小时执行:更新当天数据(实时查询用)
ALTER EVENT  evt_hourly_update_today ENABLE;

-- 启用事件:每天凌晨2点:执行昨天的数据(固化,用于历史报表) 
ALTER EVENT  evt_daily_finalize_yesterday ENABLE;

-- 查看事件详细信息
SHOW CREATE EVENT evt_hourly_update_today;
SHOW CREATE EVENT evt_daily_finalize_yesterday;

-- 暂停事件
ALTER EVENT evt_hourly_update_today DISABLE;

-- 删除事件
DROP EVENT IF EXISTS evt_hourly_update_today;

五、业务查询SQL(毫秒级响应)

5.1 查询月度日均

bash 复制代码
SELECT
    DATE_FORMAT(stat_date, '%Y-%m') AS month,
    ROUND(
        SUM(daily_unique_person) / 
        COUNT(CASE WHEN daily_unique_person > 0 THEN 1 END), 
        0
    ) AS value
FROM xy_daily_face_stats
WHERE stat_date >= DATE_FORMAT(CURDATE(), '%Y-01-01')
  AND stat_date <= CURDATE()
GROUP BY DATE_FORMAT(stat_date, '%Y-%m')
ORDER BY month;
相关推荐
linmengmeng_131425 分钟前
【总结】MyBatis-Plus批量插入与清表的正确姿势
java·spring boot·mysql·mybatis
笃行3501 小时前
别拿MySQL数据库管理工具硬导:MySQL 迁 KingbaseES 的完整工具链
数据库
风哥2号1 小时前
数据库教程FGMT51‑PostgreSQL实例管理与参数文件
数据库·postgresql
古法安卓1 小时前
Android-休眠唤醒后onLocationChanged没有数据问题排查
android·java·android studio
蓝速科技2 小时前
桌面双屏翻译机量产调试:三类场景兼容性破局方案丨蓝速科技
运维·数据库·人工智能·科技·技术分享
达梦数据2 小时前
DMDRS空间数据类型说明:Oracle、DM8、MySQL空间数据类型映射
数据库·mysql·oracle
白远山2 小时前
24小时自助健身房系统开发实战:从需求分析到完整指南
java·开发语言·数据库·数据挖掘·需求分析
达梦数据2 小时前
DMDRS服务与模块的运行步骤
数据库
lusklusklusk3 小时前
Oracle索引组织表,SQLServer聚集索引,Mysql Innodb表的数据行不是在磁盘上像排队一样严格连续地存放
mysql·postgresql·oracle·sqlserver
让学习成为一种生活方式3 小时前
PMGD:植物线粒体基因组数据库--Journal of Integrative Plant Biology
数据库