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

 更新时间:2024年08月08日 09:44:50   作者:LaFeng233  
本文主要介绍了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 = '数据库名';

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

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

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 `数据库名`;

创建成功

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 表分区内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • MySQL创建用户以及用户权限详细图文教程

    MySQL创建用户以及用户权限详细图文教程

    在MySQL中可以通过创建用户来管理数据库的访问权限,下面这篇文章主要给大家介绍了关于MySQL创建用户以及用户权限的相关资料,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2024-06-06
  • windows环境中mysql忘记root密码的解决方法详解

    windows环境中mysql忘记root密码的解决方法详解

    本篇文章是对windows环境中mysql忘记root密码的解决方法进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • 在CentOS上安装phpMyAdmin的教程

    在CentOS上安装phpMyAdmin的教程

    这篇文章主要介绍了在CentOS上安装phpMyAdmin的教程,phpMyAdmin是一款借助PHP脚本来操作MySQL的工具,非常具有人气,需要的朋友可以参考下
    2015-06-06
  • 浅谈mysql导出表数据到excel关于datetime的格式问题

    浅谈mysql导出表数据到excel关于datetime的格式问题

    这篇文章主要介绍了浅谈mysql导出表数据到excel关于datetime的格式问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07
  • mysql binlog 回滚示例解析

    mysql binlog 回滚示例解析

    严格来说mysqlbinlog 不能算回滚,他只是将过去的数据修改记录 重新执行一遍,但是从结果上来看,他也算把数据恢复到任意时间点了,这篇文章主要介绍了mysql binlog回滚示例解析,需要的朋友可以参考下
    2023-08-08
  • 3种高效的Tags标签系统数据库设计方案分享

    3种高效的Tags标签系统数据库设计方案分享

    这篇文章主要介绍了3种高效的Tags标签系统数据库设计方案分享,现在主流的博客、CMS系统都有一个标签系统,本文就探讨它的数据库设计方式,需要的朋友可以参考下
    2014-07-07
  • 登录mysql报错Can‘t connect to MySQL server on ‘localhost:3306‘ (10061)解决方法

    登录mysql报错Can‘t connect to MySQL server&n

    这篇文章主要给大家介绍了登录mysql报错 Can‘t connect to MySQL server on ‘localhost:3306‘ (10061)解决方法,文中有详细的解决步骤,需要的朋友可以参考下
    2023-09-09
  • 教你如何6秒钟往MySQL插入100万条数据的实现

    教你如何6秒钟往MySQL插入100万条数据的实现

    这篇文章主要介绍了教你如何6秒钟往MySQL插入100万条数据的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • Centos7下使用yum安装mysql数据库的详细教程(增强版)

    Centos7下使用yum安装mysql数据库的详细教程(增强版)

    这篇文章主要介绍了Centos7下使用yum安装mysql数据库的详细教程(增强版),非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-12-12
  • MySQL 表的垂直拆分和水平拆分

    MySQL 表的垂直拆分和水平拆分

    这篇文章主要介绍了MySQL 表的垂直拆分和水平拆分,文中讲解非常细致,帮助大家更好的理解和学习MySQL,感兴趣的朋友可以了解下
    2020-07-07

最新评论