mysql分区+定时生成分区

说明:

按照日期字段进行分期,每个月生成一个分区。

数据库:changsha

数据表:qiye

分期字段:riqi (分区字段必须是主键或者唯一索引)

 

操作:

1:新建表和分区

#注意分区字段riqi我也是添加到主键的哈
CREATE TABLE `qiyes` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `mingcheng` varchar(255) DEFAULT NULL,
  `daima` varchar(255) DEFAULT NULL,
  `zhucehao` varchar(255) DEFAULT NULL,
  `riqi` varchar(255) DEFAULT '',
  `dianhua` varchar(255) DEFAULT NULL,
  `dizhi` varchar(255) DEFAULT NULL,
  `zhuangtai` varchar(255) DEFAULT NULL,
  `dengji` varchar(255) DEFAULT NULL,
  `ziben` varchar(255) DEFAULT NULL,
  `fanwei` varchar(2550) DEFAULT NULL,
  `lianluoyuan` varchar(255) DEFAULT NULL,
  `lianluodianhua` varchar(255) DEFAULT NULL,
  `daidingdaibiao` varchar(255) DEFAULT NULL,
  `zhengjianhao` varchar(255) DEFAULT NULL,
  `farendianhua` varchar(255) DEFAULT NULL,
  `panding` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`,`riqi`) USING BTREE
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC

PARTITION BY RANGE COLUMNS(riqi)(
	PARTITION p20200301 VALUES LESS THAN ('2020-03'),
	PARTITION p20200401 VALUES LESS THAN ('2020-04')
)







成功后就会发现分区了,如下图

mysql分区+定时生成分区_第1张图片

2:创建一个存储过程,到时候交给定时任务调用,这存储过程的大致流程就是,先获取该表最后一个分区名,然后在逻辑判断出下一个生成的分区名应该是什么,最后执行添加分区的语句

/* 程序功能:循环使用分区,每个月一个分区
  */
 create procedure Set_Partition()
     begin

    start TRANSACTION;
 
/* 到系统表查出这个表的最大分区,得到最大分区的日期。在创建分区的时候,名称就以日期格式存放,方便后面维护 */
    select REPLACE(partition_name,'p','') into @P12_Name from INFORMATION_SCHEMA.PARTITIONS where TABLE_SCHEMA='changsha' and table_name='qiyes' order by partition_ordinal_position DESC limit 1;

/*判断最后一个分区名的月数是否大于12,如果不大于就直接加一个月,如果大于就需要加一年,并且月份设置为1月份,因为我分区名格式为20200501这种格式,所以我们新增加的分区名也要按照这个格式*/
   IF (month(@P12_Name)<12) THEN
      
          set @Max_date= DATE_FORMAT(date(DATE_SUB(@P12_Name,INTERVAL -1 MONTH)),'%Y%m01') ;
    ELSE
       set @Max_date= DATE_FORMAT(date(DATE_SUB(@P12_Name,INTERVAL -1 year)),'%Y0101') ;
    END IF;

/* 修改表,在最大分区的后面增加一个分区,时间范围1个月 ,因为我们日期范围格式是2020-05-01这格式,所以我们要格式化成这种格式*/
    SET @s1=concat('ALTER TABLE qiyes ADD PARTITION (PARTITION p',@Max_date,' VALUES LESS THAN (''',DATE_FORMAT(@Max_date,'%Y-%m-01'),'''))');
    PREPARE stmt2 FROM @s1;
    EXECUTE stmt2;
    DEALLOCATE PREPARE stmt2;


/* 提交 */
    COMMIT ;
 end;
 

3.创建定时任务,让分区可以自动生成

#每个月执行一次,从2020-05-15 16:04:00开始执行
DELIMITER ||  
DROP EVENT IF EXISTS `test` ||
  CREATE EVENT test
           ON SCHEDULE  
           EVERY 1 MONTH STARTS '2020-05-15 16:04:00'   
           DO  
        BEGIN  
  
            call Set_Partition();
         
  END ||  
 DELIMITER ; 

附加:

1.把一张表的数据插入到另一张,

#这两张表的数据结构是一样的,所以不需要指定字段,如果不一样就需要指定字段
insert into qiyes select * from qiye;

#insert  into qiyes(id,name) select id name from qiye

2.修改表的分区

alter table qiyes partition by RANGE COLUMNS(riqi) (
 PARTITION p0 VALUES LESS THAN ('2020-03-21'), #小于3月21号的放在p0分区
 PARTITION p1 VALUES LESS THAN ('2020-04-21'), #小于4月21号的放在p1分区,并且大于3月21的
 PARTITION p2 VALUES LESS THAN ('2020-05-21'), #小于5月21号的放在p2分区,并且大于4月21的
 PARTITION p3 VALUES LESS THAN ('2020-06-21'), #小于6月21号的放在p3分区,并且大于5月21的
 PARTITION p4 VALUES LESS THAN MAXVALUE #不在上面范围的都放在这个分区
);

3.查看当前表有哪些分区

select partition_name from INFORMATION_SCHEMA.PARTITIONS where TABLE_SCHEMA='changsha' and table_name='qiyes' order by partition_ordinal_position;

 

4.附加一个按照半个月来创建分区的例子

/* 程序功能:循环使用分区,每半个月一个分区,保留6个月的数据
 时间:2010-11-09 */
 drop procedure if exists Set_Partition;
 create procedure Set_Partition()
 begin
/* 事务回滚,其实放这里没什么作用,ALTER TABLE是隐式提交,回滚不了的。*/
    start TRANSACTION;
 
/* 到系统表查出这个表的最大分区,得到最大分区的日期。在创建分区的时候,名称就以日期格式存放,方便后面维护 */
    select REPLACE(partition_name,'p','') into @P12_Name from INFORMATION_SCHEMA.PARTITIONS where TABLE_SCHEMA='mydb_1' and table_name='terminal_parameter' order by partition_ordinal_position DESC limit 1;

/* 判断最大分区的时间段,如果是前半个月的,那么根据情况需要加13,14,15,16天
   如果是后半个月的,那么直接加15天。 +0 是为了把日期都格式化成YYYYMMDD这样的格式*/
    IF (DAY(@P12_Name)<=15) THEN
       CASE day(LAST_DAY(@P12_name))
          WHEN 31 THEN set @Max_date= date(DATE_ADD(@P12_Name+0,INTERVAL 16 DAY))+0 ;
          WHEN 30 THEN set @Max_date= date(DATE_ADD(@P12_Name+0,INTERVAL 15 DAY))+0 ;
          WHEN 29 THEN set @Max_date= date(DATE_ADD(@P12_Name+0,INTERVAL 14 DAY))+0 ;
          WHEN 28 THEN set @Max_date= date(DATE_ADD(@P12_Name+0,INTERVAL 13 DAY))+0 ;
       END CASE;
    ELSE
       set @Max_date= date(DATE_ADD(@P12_Name+0, INTERVAL 15 DAY))+0;
    END IF;

/* 修改表,在最大分区的后面增加一个分区,时间范围加半个月 */
    SET @s1=concat('ALTER TABLE terminal_parameter ADD PARTITION (PARTITION p',@Max_date,' VALUES LESS THAN (TO_DAYS (''',date(@Max_date),''')))');
    PREPARE stmt2 FROM @s1;
    EXECUTE stmt2;
    DEALLOCATE PREPARE stmt2;

/* 取出最小的分区的名称,并删除掉 。
    注意:删除分区会同时删除分区内的数据,慎重 */
    select partition_name into @P0_Name from INFORMATION_SCHEMA.PARTITIONS where TABLE_SCHEMA='mydb_1' and table_name='terminal_parameter' order by partition_ordinal_position limit 1;
    SET @s=concat('ALTER TABLE terminal_parameter DROP PARTITION ',@P0_Name);
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;
    DEALLOCATE PREPARE stmt1;

/* 提交 */
    COMMIT ;
 end;
 


问题:

创建分区的时候需要注意的是,分区名不能是'p2020-03-01',可以是p20200301,具体原因我也不晓得

 

参考:

http://blog.chinaunix.net/uid-24086995-id-127389.html

https://www.cnblogs.com/kawhileonardfans/p/10966833.html

 

 

 

你可能感兴趣的:(mysql笔记)