1. 程式人生 > 其它 >開發筆記 -- mysql建立動態分割槽

開發筆記 -- mysql建立動態分割槽

問題背景描述: 資料量過大時可以按某些查詢條件建立分割槽,如果這些條件時動態變化的,那麼可以根據這些條件建立動態分割槽。 HASH:分割槽主要用來確保資料在預先確定數目的分割槽中平均分佈,而在RANGE和LIST分割槽中,必須明確指定一個給定的列值或列值集合應該儲存在哪個分割槽中,而在HASH分割槽中,MySQL自動完成這些工作,你所要做的只是基於將要被雜湊的列值指定一個列值或表示式,以及指定被分割槽的表將要被分割成的分割槽數量。 RANGE:基於屬於一個給定連續區間的列值,把多行分配給同一個分割槽,這些區間要連續且不能相互重疊,使用VALUES LESS THAN操作符來進行定義。 DROP TABLES t_vehicle_capacity_car_record; #建立分割槽(根據HASH進行分割槽) CREATE TABLE `t_vehicle_capacity_car_record` ( `record_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'record_id#運力記錄id' , `province_code` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'province_code#省編號' , `city_code` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'city_code#市編號' , `district_code` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'district_code#區編號' , `capacity_car_type_id` bigint(20) NULL DEFAULT NULL COMMENT 'capacity_car_type_id#車輛型別id' , `capacity_car_type_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'capacity_car_type_name#車輛型別名稱' , `capacity_car_number` int(11) NULL DEFAULT NULL COMMENT 'capacity_car_number#車輛數量' , `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP , `province_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , `city_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , `district_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , PRIMARY KEY (`record_id`, `create_time`) )partition by hash(Month(create_time))partitions 7; #建立分割槽(根據RANGE進行分割槽) CREATE TABLE `t_vehicle_capacity_car_record` ( `record_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'record_id#運力記錄id' , `province_code` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'province_code#省編號' , `city_code` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'city_code#市編號' , `district_code` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'district_code#區編號' , `capacity_car_type_id` bigint(20) NULL DEFAULT NULL COMMENT 'capacity_car_type_id#車輛型別id' , `capacity_car_type_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'capacity_car_type_name#車輛型別名稱' , `capacity_car_number` int(11) NULL DEFAULT NULL COMMENT 'capacity_car_number#車輛數量' , `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP , `province_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , `city_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , `district_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , PRIMARY KEY (`record_id`, `create_time`) )PARTITION BY RANGE (to_days(create_time)) ( PARTITION P20180421 VALUES LESS THAN (to_days('20180425')), PARTITION P20180425 VALUES LESS THAN (to_days('20180426')), PARTITION P20180426 VALUES LESS THAN (to_days('20180427')), PARTITION P20180427 VALUES LESS THAN (to_days('20180428')) ); #建立分割槽(根據RANGE進行分割槽,然後再將RANGE分的資料進行HASH在分成3份) CREATE TABLE `t_vehicle_capacity_car_record` ( `record_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'record_id#運力記錄id' , `province_code` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'province_code#省編號' , `city_code` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'city_code#市編號' , `district_code` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'district_code#區編號' , `capacity_car_type_id` bigint(20) NULL DEFAULT NULL COMMENT 'capacity_car_type_id#車輛型別id' , `capacity_car_type_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'capacity_car_type_name#車輛型別名稱' , `capacity_car_number` int(11) NULL DEFAULT NULL COMMENT 'capacity_car_number#車輛數量' , `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP , `province_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , `city_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , `district_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , PRIMARY KEY (`record_id`, `create_time`) )PARTITION BY RANGE (to_days(create_time)) subpartition by hash(to_days(create_time)) subpartitions 3( PARTITION P20180421 VALUES LESS THAN (to_days('20180425')), PARTITION P20180425 VALUES LESS THAN (to_days('20180426')), PARTITION P20180426 VALUES LESS THAN (to_days('20180427')), PARTITION P20180427 VALUES LESS THAN (to_days('20180428')) ); #覆蓋新增分割槽 ALTER TABLE `t_vehicle_capacity_car_record` PARTITION BY RANGE (Month(create_time))( PARTITION P20180429 VALUES LESS THAN (TO_DAYS('20180429')), PARTITION P20180430 VALUES LESS THAN MAXVALUE ); #新增分割槽 ALTER TABLE `t_vehicle_capacity_car_record` add PARTITION (PARTITION P20180428 VALUES LESS THAN (TO_DAYS('20180428'))); #重新定義hash分割槽表: ALTER TABLE `t_vehicle_capacity_car_record` partition by hash(Month(create_time))partitions 7; #清空分割槽資料 TRUNCATE t_vehicle_capacity_car_record; #hasp分割槽 #HASH分割槽用月份做條件分成4個 ALTER TABLE `t_vehicle_capacity_car_record` PARTITION BY HASH (Month(create_time)) partitions 4; #HASH分割槽用天做條件分成100個 ALTER TABLE `t_vehicle_capacity_car_record` PARTITION BY HASH (Day(create_time)) partitions 100; #刪除分割槽(不會刪除分割槽資料) alter table t_vehicle_capacity_car_record REMOVE PARTITIONING; #刪除分割槽(會刪除分割槽資料) alter table t_vehicle_capacity_car_record DROP partition P20180425; #查詢分割槽 SELECT partition_name part, partition_expression expr, partition_description descr, table_rows FROM INFORMATION_SCHEMA.partitions WHERE TABLE_SCHEMA = SCHEMA() AND TABLE_NAME='t_vehicle_capacity_car_record'; #建立分割槽時間 SELECT DATE_FORMAT(DATE_SUB(curdate(),INTERVAL 0 DAY),'%Y%m%d') #動態分割槽,每天凌晨1點執行分割槽。 DROP PROCEDURE IF EXISTS PAR_ADD_MSG; #動態建立分割槽過程 CREATE PROCEDURE PAR_ADD_MSG() BEGIN DECLARE pName1 VARCHAR(20); DECLARE pName2 VARCHAR(20); DECLARE pSQL VARCHAR(200); SET pName1 = DATE_FORMAT(DATE_SUB(curdate(),INTERVAL 0 DAY),'%Y%m%d'); SET pName2 = DATE_FORMAT(DATE_SUB(curdate(),INTERVAL -1 DAY),'%Y%m%d'); SET @pSQL = CONCAT('ALTER TABLE `t_vehicle_capacity_car_record` ADD PARTITION (PARTITION P',pName1,' VALUES LESS THAN (',to_days(pName2),'))'); PREPARE stmt FROM @pSQL; EXECUTE stmt; DEALLOCATE PREPARE stmt; END DROP EVENT IF EXISTS EVENT_PAR_ADD_MSG; #JOB動態執行過程 #每天凌晨1點執行分割槽 DELIMITER ;; CREATE EVENT EVENT_PAR_ADD_MSG ON SCHEDULE EVERY 1 DAY STARTS date_add(date(curdate()),INTERVAL 1 HOUR) ON COMPLETION PRESERVE ENABLE DO BEGIN CALL PAR_ADD_MSG(); END ;; DELIMITER; SELECT * FROM t_vehicle_capacity_car_record t WHERE TO_DAYS(t.create_time) = TO_DAYS('2018-04-25'); SELECT count(1) FROM t_vehicle_capacity_car_record t;