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')
)







成功後就會發現分區了,如下圖

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

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章