ql代码
#这里使用HASH表分区,mysql会根据HASH字段来自动分配数据到不同的表分区,这种情况适用于没有表分区规则但是有需要分表来进行查询优化的情况。这里根据id字段hash规则创建2个表分区
CREATE TABLE `creater_bak` (
`id` int(11) NOT NULL,
`name` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
PARTITION BY HASH(id) PARTITIONS 2
创建完成后开始导入原表数据:
Sql代码
insert into creater_bak select * from creater;
导入以后的新表数据就是分布在不同的2个表分区中了。
如果数据量非常大,觉得预设的表分区数量太少,那么可以新增表分区,mysql会自动重新分配:
Sql代码
#这里新增8个表分区,加上新建表时候的2个,一共10个表分区了
ALTER TABLE `creater_bak` ADD PARTITION PA
Mysql不能自动创建分区,需要使用mysql event事件的方式自动创建分区
1.创建分区的存储过程如下(每次执行先校验当前分区是否存在,如果存在则不处理;不存在则创建):
DELIMITER $$#该表所在数据库名称USE `demo`$$DROP PROCEDURE IF EXISTS `create_partition_by_day`$$CREATE PROCEDURE `create_partition_by_day`(IN_SCHEMANAME VARCHAR(64), IN_TABLENAME VARCHAR(64))BEGIN #当前日期存在的分区的个数 DECLARE ROWS_CNT INT UNSIGNED; #目前日期,为当前日期的后一天 DECLARE TARGET_DATE TIMESTAMP; #分区的名称,格式为p20180620 DECLARE PARTITIONNAME VARCHAR(9); #当前分区名称的分区值上限,即为 PARTITIONNAME + 1 DECLARE PARTITION_ADD_DAY VARCHAR(9); SET TARGET_DATE = NOW() + INTERVAL 1 DAY; SET PARTITIONNAME = DATE_FORMAT( TARGET_DATE, 'p%Y%m%d' ); SET TARGET_DATE = TARGET_DATE + INTERVAL 1 DAY; SET PARTITION_ADD_DAY = DATE_FORMAT( TARGET_DATE, '%Y%m%d' ); SELECT COUNT(*) INTO ROWS_CNT FROM information_schema.partitions WHERE table_schema = IN_SCHEMANAME AND table_name = IN_TABLENAME AND partition_name = PARTITIONNAME; IF ROWS_CNT = 0 THEN SET @SQL = CONCAT( 'ALTER TABLE `', IN_SCHEMANAME, '`.`', IN_TABLENAME, '`', ' ADD PARTITION (PARTITION ', PARTITIONNAME, " VALUES LESS THAN (", PARTITION_ADD_DAY ,") ENGINE = InnoDB);" ); PREPARE STMT FROM @SQL; EXECUTE STMT; DEALLOCATE PREPARE STMT; ELSE SELECT CONCAT("partition `", PARTITIONNAME, "` for table `",IN_SCHEMANAME, ".", IN_TABLENAME, "` already exists") AS result; END IF;END$$DELIMITER ;
2.数据库定时任务(每小时执行一次)
DELIMITER $$#该表所在的数据库名称USE `demo`$$CREATE EVENT IF NOT EXISTS `daily_generate_partition`ON SCHEDULE EVERY 1 hour #执行周期,还有天、月等等STARTS '2018-06-20 00:00:00'ON COMPLETION PRESERVEENABLECOMMENT 'Creating partitions'DO BEGIN #调用刚才创建的存储过程,第一个参数是数据库名称,第二个参数是表名称 CALL datacollectcenter.create_partition_by_day('demo','test1');END$$DELIMITER ;