MySQL datetime partition problem

        Partitioning with date columns is very common in work, but sometimes you will encounter some strange problems. Hereby record the problems encountered when using the TIMESTAMP column for partitioning for the first time (because this column is affected by the database time zone and does not support partitioning, it will be described in detail below)

        Because of the need to save to milliseconds, and feel that TIMESTAMP takes up less space, the TIMESTAMP(3) data type was used at the beginning. About the data type saved to milliseconds, and the occupied space, see MySQL date time type accurate to milliseconds_Baoge66's blog - CSDN blog

        Because the log table has a large amount of data, it is partitioned by day to facilitate faster query. Query data, use the function UNIX_TIMESTAMP to write sql

ALTER TABLE `s_schedule_log` 
PARTITION BY RANGE COLUMNS (start_time) (
PARTITION p202204 VALUES LESS THAN (UNIX_TIMESTAMP('2022-05-01 00:00:00.000')),
PARTITION p20220501 VALUES LESS THAN (UNIX_TIMESTAMP('2022-05-02 00:00:00.000'))
);

        Error: Error Code: 1659. Field 'start_time' is of a not allowed type for this type of partitioning. Field 'start_time' is of a type not allowed for this type of partition. In this case, column partitioning is not used, and range partitioning is used directly to try

ALTER TABLE `s_schedule_log` 
PARTITION BY RANGE (UNIX_TIMESTAMP(start_time)) (
PARTITION p202204 VALUES LESS THAN (UNIX_TIMESTAMP('2022-05-01 00:00:00.000')),
PARTITION p20220501 VALUES LESS THAN (UNIX_TIMESTAMP('2022-05-02 00:00:00.000'))
);

        Error: Error Code: 1697. VALUES value for partition 'p202204' must have type INT. The value of VALUES for partition "p202204" must be of type INT. At this time, use select UNIX_TIMESTAMP('2022-05-01 00:00:00.000'); it is found that the printing is indeed a decimal. I decided to look for other functions. Most of the Internet uses this function. When there is no millisecond value, it can be used, but it can’t be used if there is a millisecond value. Because I couldn’t find a suitable function for a long time, I also took a chance. Anyway, I want to use the day It doesn't matter if there is still a millisecond part in the partition time. Use UNIX_TIMESTAMP('2022-05-01 00:00:00')

ALTER TABLE `s_schedule_log` 
PARTITION BY RANGE (UNIX_TIMESTAMP(start_time)) (
PARTITION p202204 VALUES LESS THAN (UNIX_TIMESTAMP('2022-05-01 00:00:00')),
PARTITION p20220501 VALUES LESS THAN (UNIX_TIMESTAMP('2022-05-02 00:00:00'))
);

        Error: Error Code: 1491. The PARTITION function returns the wrong type. The partition function returned the wrong type. This time I’m talking about something wrong with UNIX_TIMESTAMP (start_time), the type is wrong, and INT is still required. I also checked the official website. Int, string, and date types are all directly supported. You can use the UNIX_TIMESTAMP function with time, which is a little troublesome with milliseconds. Finally, I found the function to_days (I found that I am still unfamiliar with the date function , the date function library is estimated to have a lot to learn)

ALTER TABLE `s_schedule_log` 
PARTITION BY RANGE (to_days(start_time)) (
PARTITION p202204 VALUES LESS THAN (to_days('2022-05-01 00:00:00')),
PARTITION p20220501 VALUES LESS THAN (to_days('2022-05-02 00:00:00'))
);

        Error: Error Code: 1486. ​​Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed. Constant, random, or timezone-dependent expressions are not allowed in partition functions. Doesn't this mean that start_time is affected by the time zone and is limited. At this point, I have to change the data type to DATETIME(3) and continue to execute the above sql. It is found that the error is still
        reported: Error Code: 1503. A PRIMARY KEY must include all columns in the table's partitioning function. The primary key must contain all the columns of the partition function. That is, start_time is not in the primary key. (To be honest, I have a bit of a breakdown, and I feel that I have encountered all the problems that partitions will encounter, but then again, only when encountering problems can we grow in learning, and solving problems is a valuable experience in the learning process). Looking back at the official website, I found that almost all the examples on the official website did not create primary keys or indexes, so any column can create partitions. Here I have tried start_time to create an index and retrying is still the error . modify primary key

ALTER TABLE `s_schedule_log` 
CHANGE COLUMN `start_time` `start_time` DATETIME(3) NOT NULL COMMENT '开始时间' ,
DROP PRIMARY KEY,
ADD PRIMARY KEY USING BTREE (`log_id`, `start_time`);
;

        Continue to execute the above partition SQL, and the partition is created successfully! ! !

        The partition is created successfully, and then automatic partitioning is required. Please refer to MySQL to add partitions regularly_Baoge66的博客-CSDN博客

Guess you like

Origin blog.csdn.net/u011471105/article/details/124766777