需求:数据平台每天定时同步数据到本地库表tmp_a ,同步之前,会将表tmp_a 的前一天同步的数据清空,这样今天同步的数据记录很多可能和昨天的重复,要求只统计增量的数据。
思路:建立增量结果表incr_a和镜像表last_a(存昨天的数据,和源表tmp_a 数据做对比计算出增量数据插入到表incr_a)
要点:建表主键,联合索引的选取,通过源表直接建相同表结果,插入相同索引的记录时候不做任何操作insert ignore,unique key
--源表结构信息,数据平台每天定时清表,同步数据到此表,有上层平台定义结构 ,这里只是举例
CREATE TABLE tmp_a (
tax_no VARCHAR(20) NOT NULL COMMENT '列1',
raise_dt DATETIME NOT NULL COMMENT '列2',
quota DECIMAL(18,2) NOT NULL COMMENT '列3'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '上游当日全量表';
-- 建议建立联合索引提升关联速度
CREATE INDEX idx_tmp_tax_dt ON tmp_a(tax_no, raise_dt);
--------------以上的源表如果有可以不用自己定义-------------
-- 一键复制tmp_a表结构(不含数据),镜像昨天的全量数据信息
CREATE TABLE last_a LIKE tmp_a;
-- 建立联合索引用于比对join
CREATE INDEX idx_last_tax_dt ON last_a(tax_no, raise_dt);
-------------------增量表定义---------------
CREATE TABLE incr_a (
incr_id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '流水自增主键',
tax_no VARCHAR(20) NOT NULL COMMENT '所需字段1',
raise_dt DATETIME NOT NULL COMMENT '所需字段2',
op_type ENUM('add','update','delete') NOT NULL COMMENT '操作类型,当前仅存入add',
compare_date DATE NOT NULL COMMENT '比对任务执行日期',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '增量入库时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '增量结果流水表';
-- 防重试唯一索引(函数索引 MySQL8.0+)
ALTER table incr_a add UNIQUE KEY uk_incr_unique (tax_no, raise_dt);
-- 下游查询索引
CREATE INDEX idx_incr_date ON incr_a(compare_date, op_type);
---定时事件,存储过程,定时 执行存储过程,实现增量数据的写入
DELIMITER //
CREATE PROCEDURE proc_a()
BEGIN
-- 1. 比对 tmp_a VS last_a,查出新增写入增量表
INSERT IGNORE INTO incr_a (tax_no,raise_dt,op_type,compare_date)
SELECT tmp.tax_no,tmp.raise_dt,'add',CURDATE()
FROM tmp_a tmp
LEFT JOIN last_a t
ON tmp.tax_no = t.tax_no AND tmp.raise_dt = t.raise_dt
WHERE t.tax_no IS NULL;
-- 2. 更新快照:把今日全量覆盖到last_a,作为下一日比对基准
TRUNCATE TABLE last_a;
INSERT INTO last_a SELECT * FROM tmp_a;
END //
DELIMITER ;
-- 开启事件调度(重启数据库失效,my.cnf 需要配置 event_scheduler=ON 永久生效)
SET GLOBAL event_scheduler = ON;
CREATE EVENT IF NOT EXISTS event_proc_a
ON SCHEDULE EVERY 1 DAY
STARTS DATE_ADD(CURDATE(), INTERVAL 4 HOUR)
DO CALL proc_a();
-- 模拟上游T-1日数据
INSERT INTO last_a VALUES
('91000000MA00000001','2026-09-01 10:00:00',5000.00),
('91000000MA00000002','2026-09-01 14:30:00',8000.00);
select * from last_a;
INSERT INTO tmp_a VALUES
('91000000MA00000001','2026-09-01 10:00:00',5000.00),
('91000000MA00000002','2026-09-01 14:30:00',8000.00),
('91000000MA00000003','2026-09-05 09:10:00',10000.00); -- 这条是新增
SELECT * from tmp_a;
TRUNCATE tmp_a;
CALL proc_a();
select * from incr_a;
SELECT incr_id,tax_no,raise_dt,create_time,compare_date,UNIX_TIMESTAMP(raise_dt) as gxrq
FROM incr_a
WHERE compare_date = CURDATE() AND op_type = 'add';
-- 删除存储过程(重建用)
DROP PROCEDURE IF EXISTS proc_a;
-- 删除定时事件
DROP EVENT IF EXISTS event_proc_a;
-- 查看定时事件
SHOW EVENTS;
通过以上配置,就可以实现每天的全量数据取增量。