MySQL存储过程自动按年/月/日分表分区
PARTITION 创建分区
- DROP PROCEDURE IF EXISTS `proc_create_partition`;
- DELIMITER ;;
- CREATE DEFINER=`root`@`%` PROCEDURE `proc_create_partition`(
- p_table VARCHAR(128),
- p_date DATETIME,
- p_time_field VARCHAR(32),
- p_counts INT,
- p_type VARCHAR(12)
- )
- BEGIN
-
- SET @partition_table = 'p';
-
- IF( p_time_field IS NULL ) THEN
- SET p_time_field = 'pubtime';
- END IF;
-
- SET @has = NULL;
- SELECT REPLACE(`partition_name`,@partition_table,'') INTO @has
- FROM INFORMATION_SCHEMA.PARTITIONS
- WHERE table_name = p_table
- ORDER BY partition_ordinal_position DESC LIMIT 1;
-
- SET @partition_names = '';
- IF (@has IS NULL) THEN
- SET @partition_names = CONCAT('ALTER TABLE ',p_table,' PARTITION BY RANGE (TO_DAYS(',p_time_field,'))');
- ELSE
- SET @partition_names = CONCAT('ALTER TABLE ',p_table,' ADD PARTITION');
- END IF;
-
- IF( p_counts IS NULL OR p_counts < 3) THEN
- SET p_counts = 3;
- END IF;
-
- IF( p_date IS NULL ) THEN
- SET p_date = now();
- END IF;
-
- IF( p_type IS NULL ) THEN
- SET p_type = 'month';
- END IF;
-
- SET @total = p_counts;
- SET @month_time = 0;
- SET @months = '';
-
- WHILE @month_time < @total DO
- SET @time = DATE_FORMAT( DATE_ADD( p_date , INTERVAL @month_time MONTH) ,'%Y%m');
- SET @date_time = DATE_FORMAT( DATE_ADD( p_date , INTERVAL (@month_time+1) MONTH) ,'%Y-%m-01');
- IF(p_type='year') THEN
- SET @time = DATE_FORMAT( DATE_ADD( p_date , INTERVAL @month_time YEAR) ,'%Y');
- SET @date_time = DATE_FORMAT( DATE_ADD( p_date , INTERVAL (@month_time+1) YEAR) ,'%Y-01-01');
- END IF;
- IF(p_type='day') THEN
- SET @time = DATE_FORMAT( DATE_ADD( p_date , INTERVAL @month_time DAY) ,'%Y%m%d');
- SET @date_time = DATE_FORMAT( DATE_ADD( p_date , INTERVAL (@month_time+1) DAY) ,'%Y-%m-%d');
- END IF;
- SET @day_has = NULL;
- SELECT partition_name INTO @day_has
- FROM INFORMATION_SCHEMA.PARTITIONS
- WHERE table_name = p_table AND partition_name = CONCAT('p',@time)
- ORDER BY partition_ordinal_position DESC LIMIT 1;
-
- IF (@day_has IS NULL AND @total > @month_time ) THEN
- SET @months = CONCAT(@months,'PARTITION ',@partition_table,@time,' VALUES LESS THAN (TO_DAYS (''',DATE(@date_time),''')),');
- END IF;
- SET @month_time = @month_time + 1;
- END WHILE;
- IF ( length(@months) > 0 AND SUBSTRING(@months,-1) = ',' ) THEN
- SET @months = left(@months, length(@months)-1);
- END IF;
- SET @s1 = '';
- IF (@months IS NOT NULL AND @months != '') THEN
- SET @s1 = CONCAT(@partition_names,'(',@months,')');
-
- PREPARE stmt2 FROM @s1;
- EXECUTE stmt2;
- DEALLOCATE PREPARE stmt2;
- END IF;
- SELECT @s1,@days,@has,@partition_names;
-
- END;;
- DELIMITER;
-
-
-
- CALL proc_create_partition('user',now(),'pubtime',3,'year')
- CALL proc_create_partition('user',now(),'pubtime',3,'month')
- CALL proc_create_partition('user',now(),'pubtime',365,'day')
-
TABLE 创建分表
- DROP PROCEDURE IF EXISTS `proc_create_partition_table`;
- DELIMITER ;;
- CREATE DEFINER=`root`@`%` PROCEDURE `proc_create_partition_table`(
- p_dbname varchar(32),
- p_table varchar(128),
- p_tag_table varchar(128),
- p_type varchar(12),
- p_partition_type varchar(12),
- p_date datetime
- )
- BEGIN
- IF( p_date IS NULL ) THEN
- SET p_date = now();
- END IF;
-
- IF( p_type IS NULL ) THEN
- SET p_type = 'year';
- END IF;
-
- SET @table_name = CONCAT(p_table,'_',DATE_FORMAT( p_date ,'%Y'));
- IF(p_type='month') THEN
- SET @table_name = CONCAT(p_table,'_',DATE_FORMAT( p_date ,'%Y%m'));
- END IF;
-
- SET @s1 = CONCAT('CREATE TABLE ',@table_name,'(LIKE ',p_tag_table,')');
- SET @has_table = 0;
- SELECT count(1) INTO @has_table
- FROM information_schema.`tables`
- where table_type='BASE TABLE' and table_schema = p_dbname and table_name = @table_name;
- IF (@has_table = 0) THEN
-
- PREPARE stmt2 FROM @s1;
- EXECUTE stmt2;
- DEALLOCATE PREPARE stmt2;
- SELECT @s1;
-
-
- IF p_type='year' and p_partition_type = 'day' THEN
- SET @f_day = DATE_FORMAT( p_date ,'%Y-01-01');
- CALL proc_create_partition(@table_name, @f_day ,'pubtime', datediff(date_add(@f_day,interval 1 year),@f_day) ,'day');
- END IF;
- IF p_type='year' and p_partition_type = 'month' THEN
- CALL proc_create_partition(@table_name,DATE_FORMAT( p_date ,'%Y-01-01'),'pubtime',12,'month');
- END IF;
- IF p_type='month' and p_partition_type = 'day' THEN
- CALL proc_create_partition(@table_name,p_date,'pubtime',day(LAST_DAY(p_date)),'day');
- END IF;
-
-
- ELSE
- SELECT 'nothing todo' as result;
- END IF;
- END;;
- DELIMITER;
-
-
- CALL `fun_create_partition_table`('dbname','user','user','year','month','2020-01-01');
-