首先,确保 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')) );
-- 创建分区函数 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';
-- 存储过程 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 = '数据库名';
可通过修改本地系统时间,来进行反复测试是否可按照月份进行分区。
返回成功,显示已创建表分区。
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 ;
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 `数据库名`;
创建成功
插入测试数据进行测试,根据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 表分区内容请搜索插件窝以前的文章或继续浏览下面的相关文章希望大家以后多多支持插件窝!