按照日期字段进行分期,每个月生成一个分区。
数据库: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')
)
成功后就会发现分区了,如下图
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