MySQL分区表实现按月份归类


MySQL鍗曡〃鏁版嵁閲忥紝寤鸿涓嶈瓒呰繃2000W琛岋紝鍚﹀垯浼氬鎬ц兘鏈夎緝澶у奖鍝嶃傛渶杩戞帴鎵嬩簡涓涓」鐩紝鍗曡〃鏁版嵁瓒?000W琛岋紝涓鏉$畝鍗曠殑鏌ヨ璇彞绛変簡50澶氬垎閽熼兘娌″嚭缁撴灉锛屽疄鍦ㄦ槸闅惧彈锛屾渶缁堬紝鎴戜滑鍐冲畾鐢ㄥ垎鍖鸿〃銆?/p>

寤鸿〃

涓鑸殑琛紙innodb锛夊垱寤哄悗鍙湁涓涓?idb 鏂囦欢:

create table normal_table(id int primary key, no int)

鏌ョ湅鏁版嵁搴撴枃浠讹細

normal_table.ibd  

鍒涘缓鎸夋湀浠藉垎鍖虹殑鍒嗗尯琛紝娉ㄦ剰锛侀櫎浜嗗父瑙勪富閿锛屾湀浠藉瓧娈碉紙鐢ㄦ潵鍒嗗尯鐨勫瓧娈碉級涔熷繀椤绘槸涓婚敭锛?/p>

create table partition_table(id int AUTO_INCREMENT, create_date date, name varchar(10), 
primary key(id, create_date)) ENGINE=INNODB DEFAULT CHARSET=utf8 
partition by range(month(create_date))(
partition quarter1 values less than(4),
partition quarter2 values less than(7),
partition quarter3 values less than(10),
partition quarter4 values less than(13)
);

鏌ョ湅鏁版嵁搴撴枃浠讹細

partition_table#p#quarter1.ibd  
partition_table#p#quarter2.ibd  
partition_table#p#quarter3.ibd  
partition_table#p#quarter4.ibd

鎻掑叆

insert into partition_table(create_date, name) values("2021-01-25", "tom1");
insert into partition_table(create_date, name) values("2021-02-25", "tom2");
insert into partition_table(create_date, name) values("2021-03-25", "tom3");
insert into partition_table(create_date, name) values("2021-04-25", "tom4");
insert into partition_table(create_date, name) values("2021-05-25", "tom5");
insert into partition_table(create_date, name) values("2021-06-25", "tom6");
insert into partition_table(create_date, name) values("2021-07-25", "tom7");
insert into partition_table(create_date, name) values("2021-08-25", "tom8");
insert into partition_table(create_date, name) values("2021-09-25", "tom9");
insert into partition_table(create_date, name) values("2021-10-25", "tom10");
insert into partition_table(create_date, name) values("2021-11-25", "tom11");
insert into partition_table(create_date, name) values("2021-12-25", "tom12");

鏌ヨ

select count(*) from partition_table;
> 12

 
鏌ヨ绗簩涓垎鍖猴紙绗簩瀛e害锛夌殑鏁版嵁锛?
select * from partition_table PARTITION(quarter2);

4 2021-04-25 tom4
5 2021-05-25 tom5
6 2021-06-25 tom6

鍒犻櫎

褰撳垹闄よ〃鏃讹紝璇ヨ〃鐨勬墍鏈夊垎鍖烘枃浠堕兘浼氳鍒犻櫎

琛ュ厖锛歁ysql鑷姩鎸夋湀琛ㄥ垎鍖?/h2>

鏍稿績鐨勪袱涓瓨鍌ㄨ繃绋嬶細

  • auto_create_partition涓哄垱寤鸿〃鍒嗗尯锛岃皟鐢ㄥ悗涓鸿琛ㄥ垱寤哄埌涓嬫湀缁撴潫鐨勮〃鍒嗗尯銆?/li>
  • auto_del_partition涓哄垹闄よ〃鍒嗗尯锛屾柟渚垮巻鍙叉暟鎹┖闂村洖鏀躲?/li>
DELIMITER $$
DROP PROCEDURE IF EXISTS auto_create_partition$$
CREATE PROCEDURE `auto_create_partition`(IN `table_name` varchar(64))
BEGIN
   SET @next_month:=CONCAT(date_format(date_add(now(),interval 2 month),'%Y%m'),'01');
   SET @SQL = CONCAT( 'ALTER TABLE `', table_name, '`',
     ' ADD PARTITION (PARTITION p', @next_month, " VALUES LESS THAN (TO_DAYS(",
       @next_month ,")) );" );
   PREPARE STMT FROM @SQL;
   EXECUTE STMT;
   DEALLOCATE PREPARE STMT;
END$$

DROP PROCEDURE IF EXISTS auto_del_partition$$
CREATE PROCEDURE `auto_del_partition`(IN `table_name` varchar(64),IN `reserved_month` int)
BEGIN
 DECLARE v_finished INTEGER DEFAULT 0;
 DECLARE v_part_name varchar(100) DEFAULT "";
 DECLARE part_cursor CURSOR FOR 
  select partition_name from information_schema.partitions where table_schema = schema()
   and table_name=@table_name and partition_description < TO_DAYS(CONCAT(date_format(date_sub(now(),interval reserved_month month),'%Y%m'),'01'));
 DECLARE continue handler FOR 
  NOT FOUND SET v_finished = TRUE;
 OPEN part_cursor;
read_loop: LOOP
 FETCH part_cursor INTO v_part_name;
 if v_finished = 1 then
  leave read_loop;
 end if;
 SET @SQL = CONCAT( 'ALTER TABLE `', table_name, '` DROP PARTITION ', v_part_name, ";" );
 PREPARE STMT FROM @SQL;
 EXECUTE STMT;
 DEALLOCATE PREPARE STMT;
 END LOOP;
 CLOSE part_cursor;
END$$

DELIMITER ;

涓嬮潰鏄ず渚?/p>

-- 鍋囪鏈変釜琛ㄥ彨records,璁剧疆鍒嗗尯鏉′欢涓烘寜end_time鎸夋湀鍒嗗尯
DROP TABLE IF EXISTS `records`;
CREATE TABLE `records` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `start_time` datetime NOT NULL,
  `end_time` datetime NOT NULL,
  `memo` varchar(128) CHARACTER SET utf8mb4 NOT NULL,
  PRIMARY KEY (`id`,`end_time`)
) 
PARTITION BY RANGE (TO_DAYS(end_time))(
 PARTITION p20200801 VALUES LESS THAN ( TO_DAYS('20200801'))
);

DROP EVENT IF EXISTS `records_auto_partition`;

-- 鍒涘缓涓涓狤vent,姣忔湀鎵ц涓娆★紝鍚屾椂鏈澶氫繚瀛?涓湀鐨勬暟鎹?
DELIMITER $$
CREATE EVENT `records_auto_partition`
ON SCHEDULE EVERY 1 MONTH ON COMPLETION PRESERVE
ENABLE
DO
BEGIN
call auto_create_partition('records');
call auto_del_partition('records',6);
END$$
DELIMITER ;

鍑犵偣娉ㄦ剰浜嬮」锛?/p>

  • 瀵逛簬Mysql 5.1浠ヤ笂鐗堟湰鏉ヨ锛岃〃鍒嗗尯鐨勭储寮曞瓧娈靛繀椤绘槸涓婚敭
  • 瀛樺偍杩囩▼涓紝DECLARE 蹇呴』绱ц窡鐫BEGIN锛屽惁鍒欎細鎶ョ湅涓嶆噦鐨勯敊璇?/li>
  • 娓告爣鐨凞ECLARE闇瑕佸湪瀹氫箟澹版槑涔嬪悗锛屽惁鍒欎細鎶ラ敊
  • 濡傛灉鏄嚜宸卞畨瑁呯殑Mysql锛屾湁鍙兘Event鍔熻兘鏄湭寮鍚殑锛屽湪鍒涘缓Event鏃朵細鎻愮ず閿欒锛涗慨鏀筸y.cnf,鍦?[mysqld] 涓嬫坊鍔爀vent_scheduler=1鍚庨噸鍚嵆鍙?br />

鍒版杩欑瘒鍏充簬MySQL鍒嗗尯琛ㄥ疄鐜版寜鏈堜唤褰掔被鐨勬枃绔犲氨浠嬬粛鍒拌繖浜?鏇村鐩稿叧mysql鎸夋湀琛ㄥ垎鍖哄唴瀹硅鎼滅储鑴氭湰涔嬪浠ュ墠鐨勬枃绔犳垨缁х画娴忚涓嬮潰鐨勭浉鍏虫枃绔犲笇鏈涘ぇ瀹朵互鍚庡澶氭敮鎸佽剼鏈箣瀹讹紒