說明:
按照日期字段進行分期,每個月生成一個分區。
數據庫: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