開發筆記 -- mysql建立動態分割槽
阿新 • • 發佈:2022-05-25
問題背景描述: 資料量過大時可以按某些查詢條件建立分割槽,如果這些條件時動態變化的,那麼可以根據這些條件建立動態分割槽。
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;