You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL如何捕获运行的SQL查询,使用统一表存储活动历史日志?

你提出的使用统一历史表+触发器记录全业务表变更的方案,在AWS RDS MySQL环境下完全可以落地,不需要额外改造应用业务代码,仅需在数据库侧完成配置即可。

方案实现细节

1. 统一历史表结构优化

原有结构可以稍作调整,适配多场景的变更记录需求:

CREATE TABLE history_table (
    id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    table_name VARCHAR(64) NOT NULL COMMENT '变更所属业务表名',
    record_primary_key VARCHAR(64) NOT NULL COMMENT '变更行的主键值,方便回溯定位具体数据',
    column_modified VARCHAR(64) COMMENT '变更字段名,整行插入/删除时可填NULL',
    action ENUM('insert', 'update', 'delete') NOT NULL COMMENT '操作类型',
    data_before_modify JSON COMMENT '变更前数据,insert操作时可填NULL',
    data_after_modify JSON COMMENT '变更后数据,delete操作时可填NULL',
    date_modified DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '变更时间,精确到毫秒避免并发冲突',
    INDEX idx_table_date (table_name, date_modified),
    INDEX idx_record_pk (table_name, record_primary_key)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

这里使用JSON类型存储前后数据,相比字符串格式更灵活,后续查询过滤也更方便。

2. 触发器编写示例

插入触发器

DROP TRIGGER IF EXISTS game_data_insert;
DELIMITER //
CREATE TRIGGER game_data_insert AFTER INSERT ON game_data FOR EACH ROW
BEGIN
    INSERT INTO history_table (
        table_name, record_primary_key, action, data_after_modify
    ) VALUES (
        'game_data', NEW.id, 'insert', JSON_OBJECT(
            'season_data', NEW.season_data,
            'other_column1', NEW.other_column1,
            'other_column2', NEW.other_column2
            -- 业务表其他字段依次补充即可
        )
    );
END //
DELIMITER ;

更新触发器

DROP TRIGGER IF EXISTS game_data_update;
DELIMITER //
CREATE TRIGGER game_data_update AFTER UPDATE ON game_data FOR EACH ROW
BEGIN
    -- 增加判断仅记录真实发生变更的字段,避免生成无意义日志
    IF OLD.season_data <> NEW.season_data THEN
        INSERT INTO history_table (
            table_name, record_primary_key, column_modified, action, data_before_modify, data_after_modify
        ) VALUES (
            'game_data', OLD.id, 'season_data', 'update', OLD.season_data, NEW.season_data
        );
    END IF;
    -- 其他需要监听的字段可依次增加IF判断逻辑
END //
DELIMITER ;

删除触发器

DROP TRIGGER IF EXISTS game_data_delete;
DELIMITER //
CREATE TRIGGER game_data_delete AFTER DELETE ON game_data FOR EACH ROW
BEGIN
    INSERT INTO history_table (
        table_name, record_primary_key, action, data_before_modify
    ) VALUES (
        'game_data', OLD.id, 'delete', JSON_OBJECT(
            'season_data', OLD.season_data,
            'other_column1', OLD.other_column1,
            'other_column2', OLD.other_column2
            -- 业务表其他字段依次补充即可
        )
    );
END //
DELIMITER ;

注意事项

  • AWS RDS MySQL默认已开放触发器使用权限,无需额外调整实例参数,仅需确保操作账号持有TRIGGER权限即可正常创建触发器。
  • 高并发场景下需关注history_table的写入性能,可通过按时间分表、调整InnoDB刷盘参数等方式优化,避免影响原业务表的写入效率。
  • 若业务表字段有增删变更,需同步更新对应触发器的字段逻辑,避免遗漏变更记录。
  • 不要在触发器中加入复杂计算、跨表查询等逻辑,否则会大幅拖慢原业务的写入速度。

内容的提问来源于stack exchange,提问作者zack_falcon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 19:39:02