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;
相关推荐
高级程序源7 小时前
django校园寻物通失物招领平台32261-计算机课程设计、毕业设计
vue.js·python·mysql·小程序·django·flask·课程设计
KIDULT°7 小时前
MySQL系列 (1):数据库原理
运维·数据库·mysql·云计算
我不是程序员三三7 小时前
透明加密软件偶发解密异常排错实录:文件时能打开时乱码
数据库·域智盾
snhna7 小时前
向量数据库深度实战:从 HNSW 到 pgvector、Milvus 选型与 RAG 落地
数据库·人工智能·python·postgresql·milvus
天行健,君子而铎8 小时前
数据分类分级的范式转换:从规则匹配到场景化高准确率一键部署
网络·数据库·安全
牛战士coding8 小时前
MySQL 读写分离完整链路:主从复制、多数据源与 @DS 路由
数据库·mysql
goehou9 小时前
MCP 查数实战:让 LLM 安全地查数据库(只读账号、SQL 校验、参数漂移)
数据库·ai·llm·教程·mcp·function calling
我不会插花弄玉9 小时前
7.函数【由浅入深-MySQL】
android·数据库·mysql
周小董10 小时前
[1369]Windows上安装PostgreSQL
数据库·windows·postgresql
vilya10 小时前
手机端 Agent 怎么动起来:Kotlin 与 Python 之间的桥
android·agent