最新公告
  • 欢迎您光临码农资源网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!加入我们
  • MySQL按月自动设置表分区的实现

    开始检查

    首先,确保 ticket_history_info表是一个分区表。如果未设置分区,需要修改表结构以支持分区,将 ticket_history_info 表设置为按日期范围进行分区

    ALTER TABLE ticket_history_info
    PARTITioN BY RANGE (TO_DAYS(CALL_DATE)) (
        PARTITION p0 VALUES LESS THAN (TO_DAYS('2022-09-01'))
    );
    

    1.创建分区函数

    -- 创建分区函数
    DELIMITER //
    CREATE FUNCTION get_partition_name(p_date DATE)
    RETURNS VARCHAR(20)
    DETERMINISTIC
    BEGIN
        DECLARE p_month VARCHAR(2);
        DECLARE p_year VARCHAR(4);
        SET p_month = LPAD(MONTH(p_date), 2, '0');
        SET p_year = YEAR(p_date);
        RETURN CONCAT('p', p_year, p_month); 
    END//
    DELIMITER ;
    

    检查是否成功创建函数

    SHOW FUNCTION STATUS LIKE 'get_partition_name';

    2.创建存储过程,用于自动生成分区

    -- 存储过程
    DELIMITER //
    CREATE PROCEDURE create_monthly_partition()
    BEGIN
        DECLARE next_month VARCHAR(20);
        DECLARE next_month_first_day DATE;
        
        -- 计算下一个月份的名称和下个月的第一天
        SET next_month = CONCAT('p', DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 1 MONTH), '%Y%m'));
        SET next_month_first_day = LAST_DAY(DATE_ADD(CURDATE(), INTERVAL 1 MONTH)) + INTERVAL 1 DAY;
        
        -- 检查分区是否已存在
        IF NOT EXISTS (
            SELECT NULL
            FROM information_schema.PARTITIONS
            WHERE TABLE_NAME = 'ticket_history_info' AND TABLE_SCHEMA = 'ccm' AND PARTITION_NAME = next_month
        ) THEN
            -- 创建新的分区
            SET @sql = CONCAT('ALTER TABLE ticket_history_info ADD PARTITION (PARTITION ', next_month, ' VALUES LESS THAN (TO_DAYS('', next_month_first_day, '')))');
    
            PREPARE stmt FROM @sql;
            EXECUTE stmt;
            DEALLOCATE PREPARE stmt;
        END IF;
    END//
    DELIMITER ;

     进行测试

     检查是否成功创建函数

    SHOW PROCEDURE STATUS LIKE 'create_monthly_partition';

    执行函数

    CALL create_monthly_partition();

    查询表分区,查看是否成功分区。

    SELECT PARTITION_NAME FROM information_schema.PARTITIONS WHERE TABLE_NAME = '表名' AND TABLE_SCHEMA = '数据库名';

    可通过修改本地系统时间,来进行反复测试是否可按照月份进行分区。

    MySQL按月自动设置表分区的实现

    返回成功,显示已创建表分区。

    MySQL按月自动设置表分区的实现

    3.创建自动删除半年以前的表空间函数

    DELIMITER //
    
    CREATE PROCEDURE delete_old_partitions()
    BEGIN
        DECLARE done INT DEFAULT FALSE;
        DECLARE drop_partition_name VARCHAR(64);
        DECLARE cur CURSOR FOR 
            SELECT PARTITION_NAME 
            FROM information_schema.PARTITIONS 
            WHERE TABLE_SCHEMA = '数据库名' 
              AND TABLE_NAME = 'ticket_history_info' 
              AND PARTITION_DESCRIPTION < TO_DAYS(NOW() - INTERVAL 6 MONTH);
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    
        OPEN cur;
    
        read_loop: LOOP
            FETCH cur INTO drop_partition_name;
            IF done THEN
                LEAVE read_loop;
            END IF;
            SET @sql = CONCAT('ALTER TABLE ticket_history_info DROP PARTITION ', drop_partition_name);
            PREPARE stmt FROM @sql;
            EXECUTE stmt;
            DEALLOCATE PREPARE stmt;
        END LOOP;
    
        CLOSE cur;
    
       -- 删除超过半年的数据
        DELETE FROM ticket_history_info_copy1
        WHERE CALL_DATE < CURDATE() - INTERVAL 6 MONTH;
    
    END//
    
    DELIMITER ;
    

    4.创建调度任务,修改到每月最后一天执行执行存储过程

    CREATE EVENT IF NOT EXISTS monthly_partition_event
    ON SCHEDULE EVERY 1 MONTH
    STARTS CONCAT(DATE_FORMAT(LAST_DAY(CURRENT_DATE), '%Y-%m-'), DAY(LAST_DAY(CURRENT_DATE)), ' 23:00:00')
    DO
    BEGIN
        CALL create_monthly_partition();
        CALL delete_old_partitions();
    END;
    

    查看事件调度器是否启动

    SET GLOBAL event_scheduler = ON;

    查看事件

    SHOW EVENTS;
    

    SHOW EVENTS FROM `数据库名`;

    创建成功

    MySQL按月自动设置表分区的实现

    5.进行测试

    插入测试数据进行测试,根据CALL_DATE字段进行数据分区,

    INSERT INTO ticket_history_info (CALL_DATE, SRC_ADD, CALLING_NUM, DURATION) VALUES
    ('2024-05-24 00:00:00', 'Address1', '1234567890', 60),
    ('2024-06-20 00:00:00', 'Address2', '0987654321', 120),
    ('2024-05-10 00:00:00', 'Address3', '1122334455', 180),
    ('2024-10-01 00:00:00', 'Address4', '5566778899', 240);

    -查询每个分区的行数

    SELECT PARTITION_NAME, TABLE_ROWS
    FROM information_schema.PARTITIONS
    WHERE TABLE_SCHEMA = 'ccm' AND TABLE_NAME = 'ticket_history_info';

    或者单独查询某一个分区的数据

    SELECT *
    FROM ticket_history_info PARTITION (p202406);

    到此这篇关于Mysql按月自动设置表分区的实现的文章就介绍到这了,更多相关mysql 表分区内容请搜索编程网(www.lsjlt.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网(www.lsjlt.com)! 

    想要了解更多内容,请持续关注码农资源网,一起探索发现编程世界的无限可能!
    本站部分资源来源于网络,仅限用于学习和研究目的,请勿用于其他用途。
    如有侵权请发送邮件至1943759704@qq.com删除

    码农资源网 » MySQL按月自动设置表分区的实现
    • 7会员总数(位)
    • 25846资源总数(个)
    • 0本周发布(个)
    • 0 今日发布(个)
    • 293稳定运行(天)

    提供最优质的资源集合

    立即查看 了解详情