大家好,我是烤鸭:
今天分享一下有关 mysql 分区。
需求:
按时间分区。 对千万数据左右的表,进行分区,数据的增加量大概千万/年。
代码实现:
模拟之前已经存在的表:
DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',`description` varchar(512) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,`state` tinyint(4) NULL DEFAULT 0 COMMENT '0:未处理,1:处理中,2:处理完成,3:异常订单',`create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间'
) ;
#取消自增
alter table test modify id int;
#删除主键
alter table test drop PRIMARY KEY;
#添加复合主键
alter table test add PRIMARY KEY(id,create_time);
#id 改为自增
alter table test modify id int AUTO_INCREMENT;
#增加组合索引,分区的字段必须是唯一,所以唯一索引无法创建。
#ALTER TABLE test ADD UNIQUE (serial_no,delete_flag);
#增加分区,按时间 1 年
ALTER TABLE test PARTITION BY RANGE COLUMNS(create_time ) (PARTITION p1 VALUES LESS THAN ( '20190101'),PARTITION p2 VALUES LESS THAN ( '20200101'),PARTITION p3 VALUES LESS THAN ( '20210101'),PARTITION p4 VALUES LESS THAN ( '20220101'),PARTITION p5 VALUES LESS THAN ( '20230101'),PARTITION p6 VALUES LESS THAN ( '20240101'),PARTITION p7 VALUES LESS THAN ( '20250101'),PARTITION p8 VALUES LESS THAN ( '20260101'),PARTITION p9 VALUES LESS THAN ( '20270101')
);
简单介绍:
mysql分区类型
RANGE 分区:
基于属于一个给定连续区间的列值,把多行分配给分区。
LIST 分区:
类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择。
HASH分区:
基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包含MySQL中有效的、产生非负整数值的任何表达式。
KEY分区:
类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL服务器提供其自身的哈希函数。必须有一列或多列包含整数值。
复合分区:
基于RANGE/LIST 类型的分区表中每个分区的再次分割。子分区可以是 HASH/KEY 等类型。
常用的命令:
#创建表时分区:
CREATE TABLE `test` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',`description` varchar(512) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,`state` tinyint(4) NULL DEFAULT 0 COMMENT '0:未处理,1:处理中,2:处理完成,3:异常订单',`create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',PRIMARY KEY (`id`) USING BTREE,INDEX `etc_cg_document_i4`(`state`) USING BTREE,
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Compact PARTITION BY RANGE (`id`)PARTITIONS 2(PARTITION `p1` VALUES LESS THAN (10000) ENGINE = InnoDB MAX_ROWS = 0 MIN_ROWS = 0 ,PARTITION `p2` VALUES LESS THAN (20000) ENGINE = InnoDB MAX_ROWS = 0 MIN_ROWS = 0 )
;
#增加分区:(以id分区)
alter table test partition by range(id)
(partition p1 values less than (10000),partition p2 values less than (20000)
);
#删除指定分区:
alter table test drop partition p1;
#删除所有分区:
Alter table test remove partitioning;
#查看分区信息
SELECTPARTITION_NAME,TABLE_ROWS
FROMINFORMATION_SCHEMA.PARTITIONS
WHERETABLE_NAME = 'test';
另外说下,如果删除分区,指定分区的数据也会同步删除,谨慎操作。
如果想mysql重建表分区并保留数据的的话,参考这篇:
https://blog.csdn.net/fdipzone/article/details/79769524
关于大数据量 mysql 优化看这篇:
https://blog.csdn.net/afsvsv/article/details/84998119
关于更多 mysql 分区的信息 看这篇文章:
https://www.cnblogs.com/sweet521/p/6439598.html