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;
相关推荐
怪奇云呼军12 小时前
从声音特征到 CRM 回流:闪电智能 Voice Agent 沟通策略自适应系统 v1 实战
android·人工智能·python·音视频·语音识别
曹牧13 小时前
C#:问号
前端·数据库·c#
奇树谦13 小时前
《现代 Key-Value 数据库原理:从 B+Tree 到 LSM Tree》-第五篇:现代数据库横向对比
数据库·lsm-tree
李白客13 小时前
分布式集群与数据库产业:从单机到集群的架构跃迁与市场重构
数据库·分布式·架构
福大大架构师每日一题14 小时前
Redis 8.10.0 正式发布:紧凑哈希、批量导入、备份恢复、流与时序能力全面升级
数据库·redis·哈希算法
一笑的小酒馆14 小时前
Android视频直播播放器简单封装
android
雨晨源码(同名B站)14 小时前
基于深度学习YoloV11农业病害虫害检测系统 智慧农业信息化综合管理平台 (附源码+lw文档+ppt)
数据库·人工智能·深度学习·yolo·信息可视化
DBA小马哥15 小时前
向量数据库入门到进阶:Embedding、ANN算法与RAG落地的关键术语
数据库·算法·embedding
云和数据.ChenGuang15 小时前
fastapi项目拆分实战数据模型
java·服务器·数据库·人工智能·深度学习·fastapi·强化学习
祈禾15 小时前
Redis三大特殊数据类型
运维·服务器·数据库·redis·笔记·缓存