首先是寫一個存儲過程,還是比較簡單的,主要是網上有很多現成的,大部分有點錯誤。下邊的是實際應用過程中實戰有效的。沒有錯誤的。
首先是存儲過程展示;
DELIMITER $$
DROP PROCEDURE IF EXISTS `create_Partition`$$
CREATE DEFINER=`root`@`%` PROCEDURE `create_Partition`(IN databaseName VARCHAR(50),IN tableName VARCHAR(50))
L_END:BEGIN
DECLARE MAX_PARTITION_DESCRIPTION VARCHAR(255) DEFAULT 0;
DECLARE P_NAME VARCHAR(255) DEFAULT 0;
DECLARE P_DESCRIPTION VARCHAR(255) DEFAULT 0;
DECLARE i INT DEFAULT 1;
DECLARE ISEXIST_PARTITION VARCHAR(255) DEFAULT 0;
DECLARE MONTH_DAYS VARCHAR(5);
DECLARE YEAR_NUM VARCHAR(10);
DECLARE MONTH_NUM VARCHAR(5);
SELECT PARTITION_NAME INTO ISEXIST_PARTITION FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA = databaseName AND TABLE_NAME = tableName LIMIT 1 ;
IF ISEXIST_PARTITION <=> "" THEN
SELECT "Partition table not is exist" AS "*****ERROR*****";
LEAVE L_END;
END IF;
SELECT partition_description INTO MAX_PARTITION_DESCRIPTION FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA = databaseName AND TABLE_NAME = tableName ORDER BY partition_description DESC LIMIT 1;
IF MAX_PARTITION_DESCRIPTION <=> "" THEN
SELECT "Partition table is error" AS "*****ERROR*****";
LEAVE L_END;
END IF;
select day(last_day(date_add(NOW(), interval 1 MONTH)))into MONTH_DAYS;
SET MAX_PARTITION_DESCRIPTION = REPLACE(MAX_PARTITION_DESCRIPTION, '\'', '');
WHILE i <= MONTH_DAYS DO
select date_format(date_add(last_day(NOW()),interval i day),'%Y-%m-%d') into P_DESCRIPTION;
## SET P_DESCRIPTION = adddate(MAX_PARTITION_DESCRIPTION, INTERVAL i day);
SET P_NAME = REPLACE(P_DESCRIPTION, '-', '');
SET @S=CONCAT('ALTER TABLE ',tableName,' ADD PARTITION (PARTITION p',P_NAME,' VALUES LESS THAN (','\'',P_DESCRIPTION,'\'','))');
SELECT @S;
PREPARE stmt2 FROM @S;
EXECUTE stmt2;
DEALLOCATE PREPARE stmt2;
SET i = i + 1 ;
END WHILE;
END L_END$$
DELIMITER ;
別看這麼長,實際用到的只是while部分。其餘部分就是判斷有效性和查詢數據,爲自動分區做準備數據用的。
寫好了存儲過程可以自己建一張表測試一下。
CREATE TABLE `realtable` (
`id` int(10) unsigned NOT NULL COMMENT '表主鍵',
`pid` int(10) unsigned NOT NULL COMMENT '產品ID',
`price` decimal(15,2) NOT NULL COMMENT '單價',
`num` int(11) NOT NULL COMMENT '購買數量',
`uid` int(10) unsigned NOT NULL COMMENT '客戶ID',
`atime` varchar(255) NOT NULL DEFAULT '',
`utime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '修改時間',
PRIMARY KEY (`id`,`atime`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
/*!50500 PARTITION BY RANGE COLUMNS(atime)
(PARTITION p30 VALUES LESS THAN ('2018-07-09') ENGINE = InnoDB,
PARTITION p31 VALUES LESS THAN ('2018-07-10') ENGINE = InnoDB,
PARTITION p32 VALUES LESS THAN ('2018-07-11') ENGINE = InnoDB,
PARTITION p33 VALUES LESS THAN ('2018-07-12') ENGINE = InnoDB,
PARTITION p20180801 VALUES LESS THAN ('2018-08-01') ENGINE = InnoDB,
PARTITION p20180802 VALUES LESS THAN ('2018-08-02') ENGINE = InnoDB,
PARTITION p20180803 VALUES LESS THAN ('2018-08-03') ENGINE = InnoDB,
PARTITION p20180804 VALUES LESS THAN ('2018-08-04') ENGINE = InnoDB,
PARTITION p20180805 VALUES LESS THAN ('2018-08-05') ENGINE = InnoDB,
PARTITION p20180806 VALUES LESS THAN ('2018-08-06') ENGINE = InnoDB,
PARTITION p20180807 VALUES LESS THAN ('2018-08-07') ENGINE = InnoDB,
PARTITION p20180808 VALUES LESS THAN ('2018-08-08') ENGINE = InnoDB,
PARTITION p20180809 VALUES LESS THAN ('2018-08-09') ENGINE = InnoDB,
PARTITION p20180810 VALUES LESS THAN ('2018-08-10') ENGINE = InnoDB,
PARTITION p20180811 VALUES LESS THAN ('2018-08-11') ENGINE = InnoDB,
PARTITION p20180812 VALUES LESS THAN ('2018-08-12') ENGINE = InnoDB,
PARTITION p20180813 VALUES LESS THAN ('2018-08-13') ENGINE = InnoDB,
PARTITION p20180814 VALUES LESS THAN ('2018-08-14') ENGINE = InnoDB,
PARTITION p20180815 VALUES LESS THAN ('2018-08-15') ENGINE = InnoDB,
PARTITION p20180816 VALUES LESS THAN ('2018-08-16') ENGINE = InnoDB,
PARTITION p20180817 VALUES LESS THAN ('2018-08-17') ENGINE = InnoDB,
PARTITION p20180818 VALUES LESS THAN ('2018-08-18') ENGINE = InnoDB,
PARTITION p20180819 VALUES LESS THAN ('2018-08-19') ENGINE = InnoDB,
PARTITION p20180820 VALUES LESS THAN ('2018-08-20') ENGINE = InnoDB,
PARTITION p20180821 VALUES LESS THAN ('2018-08-21') ENGINE = InnoDB,
PARTITION p20180822 VALUES LESS THAN ('2018-08-22') ENGINE = InnoDB,
PARTITION p20180823 VALUES LESS THAN ('2018-08-23') ENGINE = InnoDB,
PARTITION p20180824 VALUES LESS THAN ('2018-08-24') ENGINE = InnoDB,
PARTITION p20180825 VALUES LESS THAN ('2018-08-25') ENGINE = InnoDB,
PARTITION p20180826 VALUES LESS THAN ('2018-08-26') ENGINE = InnoDB,
PARTITION p20180827 VALUES LESS THAN ('2018-08-27') ENGINE = InnoDB,
PARTITION p20180828 VALUES LESS THAN ('2018-08-28') ENGINE = InnoDB,
PARTITION p20180829 VALUES LESS THAN ('2018-08-29') ENGINE = InnoDB,
PARTITION p20180830 VALUES LESS THAN ('2018-08-30') ENGINE = InnoDB,
PARTITION p20180831 VALUES LESS THAN ('2018-08-31') ENGINE = InnoDB) */;
其中7月份是手動建的,其餘的是調用改存儲過程生成的。
調用SQL語句:
CALL create_Partition('liuhua','realtable');
可能在調用過程中會報錯root不存在,此時需要授權一下。SQL語句如下。
grant all privileges on *.* to root@"%" identified by ".";
這樣就可以實現按照天自動分區。
存儲過程寫完了,分區效果實現了,那麼就可以寫一個事件去執行了。
DELIMITER $$
CREATE DEFINER=`root`@`%` EVENT `auto_set_partitions`
ON SCHEDULE EVERY 1 MONTH STARTS '2018-08-11 17:18:00'
ON COMPLETION PRESERVE ENABLE
DO
BEGIN
CALL create_Partition('liuhua','realtable');
END $$
DELIMITER ;
注意:1 該存儲過程就幾乎不需要修改就可以直接使用;
2 其中的時間字段是varcha類型的,其他的時間類型會報錯,類型不正確。
3 可以修改的地方,存儲過程的嗎名字,和時間字段的格式。
具體的內容意思就不做詳細介紹了。