Mysql支持range分区(每个分区包含分区表达式的值位于一个给定的连续区间内的行本文会着重介绍),hash分区(无需定义分区的条件,数据会平均分配到每个分区。只需要指明分区数即可,如下
ALTER TABLE "yesterday_last_alarm" PARTITION BY HASH(TO_DAYS(statistics_time)) PARTITIONS 30;
),
key分区(跟hash分区有点类似)
1. KEY分区允许多列,而HASH分区只允许一列。
2. 如果在有主键或者唯一键的情况下,key中分区列可不指定,默认为主键或者唯一键,如果没有,则必须显性指定列。
3. KEY分区对象必须为列,而不能是基于列的表达式。
4. KEY分区和HASH分区的算法不一样,PARTITION BY HASH (expr),MOD取值的对象是expr返回的值,而PARTITION BY KEY (column_list),基于的是列的MD5值,如下
CREATE TABLE tb_keyline (
id INT NOT NULL,
var CHAR(5)
)
PARTITION BY LINEAR KEY (var)
PARTITIONS 3;
本文着重介绍下range分区的动态创建,主要是基于yesterday_last_alarm这张表数据以天为单位进行分区操作,每天凌晨12点自动创建一个分区用于新增数据。
1、在进行自动增加分区前一定得先对表手动分几个区
ALTER TABLE `yesterday_last_alarm` PARTITION BY RANGE (TO_DAYS(statistics_time))
(
PARTITION p1201 VALUES LESS THAN (TO_DAYS("-12-01")),
PARTITION p1202 VALUES LESS THAN (TO_DAYS("-12-02")),
PARTITION p1203 VALUES LESS THAN (TO_DAYS("-12-03")),
PARTITION p1204 VALUES LESS THAN (TO_DAYS("-12-04")),
PARTITION p1205 VALUES LESS THAN (TO_DAYS("-12-05")),
PARTITION p1206 VALUES LESS THAN (TO_DAYS("-12-06")),
PARTITION p1207 VALUES LESS THAN (TO_DAYS("-12-07"))
)
2、分区存储过如下:
DELIMITER $$
USE `yx_zd_wh`$$
DROP PROCEDURE IF EXISTS `p_add_partion_proc`$$
CREATE DEFINER=`root`@`%` PROCEDURE `p_add_partion_proc`()
BEGIN
/* 事务回滚,其实放这里没什么作用,ALTER TABLE是隐式提交,回滚不了的。*/
DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK;
START TRANSACTION;
/* 到系统表查出这个表的最大分区,得到最大分区的日期。在创建分区的时候,名称就以日期格式存放,方便后面维护 */
SELECT REPLACE(partition_name,"p","") INTO @P12_Name FROM INFORMATION_SCHEMA.PARTITIONS
WHERE table_name="yesterday_last_alarm" AND partition_name!="pmax" ORDER BY partition_ordinal_position DESC LIMIT 1;
/*直接加7天,就是得到7天之后的日期。+0 是为了把日期都格式化成YYYYMMDD这样的格式*/
SET @Max_date= DATE(DATE_ADD(@P12_Name+0, INTERVAL 1 DAY))+0;
/* 修改表,在最大分区的后面增加一个分区,时间范围加1天 */
SET @s1=CONCAT("ALTER TABLE yesterday_last_alarm ADD PARTITION (PARTITION p",@Max_date," VALUES LESS THAN (TO_DAYS (""",DATE(@Max_date),""")))");
/* 输出查看增加分区语句*/
SELECT @s1;
PREPARE stmt2 FROM @s1;
EXECUTE stmt2;
DEALLOCATE PREPARE stmt2;
/* 取出最小的分区的名称,并删除掉 。
注意:删除分区会同时删除分区内的数据,慎重 */
/*select partition_name into @P0_Name from INFORMATION_SCHEMA.PARTITIONS
where table_name="tb_3a_huandan_detail" order by partition_ordinal_position limit 1;
SET @s=concat("ALTER TABLE tb_3a_huandan_detail DROP PARTITION ",@P0_Name);
PREPARE stmt1 FROM @s;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1; */
/* 提交 */
COMMIT ;
END$$
DELIMITER ;
)
3、增加定时事件
/**DELIMITER ||
CREATE EVENT "create_partition_day_event"
ON SCHEDULE
EVERY 1 day STARTS "-12-08 00:00:00"
DO
BEGIN
CALL yx_zd_wh.`p_add_partion_proc`;
END ||
DELIMITER ;**/
DELIMITER $$
CREATE DEFINER=`root`@`localhost` EVENT `create_partition_day_event` ON SCHEDULE EVERY 1 DAY STARTS "-12-08 00:00:00" ON COMPLETION NOT PRESERVE ENABLE DO CALL p_add_partion_proc()$$
DELIMITER ;
4查询分区
SELECT * FROM INFORMATION_SCHEMA.partitions
WHERE TABLE_SCHEMA = schema() AND TABLE_NAME="yesterday__last_alarm";