我创建了一个表来记录我的应用程序的活动。该表每月将记录超过 200 万条记录。所以我想使用按月或按周分区
CREATE TABLE IF NOT EXISTS `UL`.`Log` (
`LogID` INT(20) NOT NULL AUTO_INCREMENT,
`LogDate` DATETIME NULL,
`AssessorName` VARCHAR(255) NULL
PRIMARY KEY (`LogID`),
INDEX `AssessorName` (`AssessorName`),
INDEX `LogDate` (`LogDate`)
)
ENGINE = INNODB;
但问题是我必须手动创建分区,例如
PARTITION BY RANGE (EXTRACT(YEAR_MONTH FROM LogDate)) (
PARTITION pre_2014 VALUES LESS THAN (201400),
PARTITION jan_2014 VALUES LESS THAN (201401),
PARTITION feb_2014 VALUES LESS THAN (201402),
....
有什么办法可以自动按月或按周创建分区吗?
谢谢
不要使用
YEAR_MONTH()
,它不在此处的列表中:http://dev.mysql.com/doc/refman/5.6/en/partitioning-limitations-functions.html
相反,请使用
TO_DAYS(LogDate)
和明确的日期,例如 '2014-01-01'
。
不,没有“自动”分区。 编写 Perl(或其他语言)代码来从
information_schema
获取分区结构并计算接下来要添加的分区并不是太困难的任务。
您希望从
PARTITIONing
中获得什么? 好处很少。 我已将它们列出在我的博客中。
此外,该链接还包含用于处理清除旧分区的代码,以及如何每周(或每月)有效地使用
REORGANIZE PARTITIONS
。
MySQL
CREATE TABLE ...
PARTITION BY
HASH (
MOD((TO_DAYS(created) DIV 7) + 1, 12)
) PARTITIONS 12;
创建12个分区,每个分区以循环方式恰好存储7天。
您可以通过使用 mysql/mariadb 调度程序截断分区并定义 EVENT 来清除分区以供下周存储。
-- enable scheduler
SET GLOBAL event_scheduler = ON;
-- define cleanup event procedure
DELIMITER //
CREATE EVENT my_table_cleanup
ON SCHEDULE EVERY 1 WEEK
STARTS '2024-10-31 23:00:00'
DO
BEGIN
DECLARE partition_name VARCHAR(255);
-- Calculate the partition name based on the modulo formula
SET @partition_number = MOD((TO_DAYS(created) DIV 7) + 1, 12);
SET partition_name = CONCAT('p', @partition_number);
-- Construct the dynamic SQL query to truncate the partition
SET @truncate_query = CONCAT('ALTER TABLE logs TRUNCATE PARTITION ', partition_name);
-- Prepare, execute, and deallocate the statement
PREPARE stmt FROM @truncate_query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END;
//
DELIMITER ;
请注意,解决方案可能不一定与标准周一致,因为它是从“0”年开始计算周数的。请参阅
TO_DAYS()
函数文档了解更多信息。