视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
数据切分Mysql分区表的管理与维护_MySQL
2020-11-09 19:46:37 责编:小采
文档
 Mysql支持4种表的分区,即RANGE与LIST、HASH与KEY,其中RANGE和LIST类似,按一种区间进行分区,HASH与KEY类似,是按照某种算法对字段进行分区。

RANGE与LIST分区管理:

案例:有一个聊天记录表,用户几千左右,已经对表按照用户进行一定粒度的水平分割,现仍然有部分表存储的记录比较多,于是按照下列方式有对表进行了分区,分区的好处是,可以动态改变分区,删除分区后,数据也一同被删除,如聊天记录只保存两年,那么你就可以按照时间进行分区,定期删除两年前的分区,动态创建新的的分区就能做到很好的数据维护。

分区表创建的语句如下:

DROP TABLE IF EXISTS `msgss`;
CREATE TABLE `msgss` (
 `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '表主键',
 `sender` int(10) unsigned NOT NULL COMMENT '发送者ID',
 `reciver` int(10) unsigned NOT NULL COMMENT '接收者ID',
 `msg_type` tinyint(3) unsigned NOT NULL COMMENT '消息类型',
 `msg` varchar(225) NOT NULL COMMENT '消息内容',
 `atime` int(10) unsigned NOT NULL COMMENT '发送时间',
 `sub_id` tinyint(3) unsigned NOT NULL COMMENT '部门ID',
 PRIMARY KEY (`id`,`atime`,`sub_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*********分区信息**************/
PARTITION BY RANGE (atime) SUBPARTITION BY HASH (sub_id) 
(
	PARTITION t0 VALUES LESS THAN(1451577600)
	(
	SUBPARTITION s0,
	SUBPARTITION s1,
	SUBPARTITION s2,
	SUBPARTITION s3,
	SUBPARTITION s4,
	SUBPARTITION s5
	),
	PARTITION t1 VALUES LESS THAN(1483200000)
	(
	SUBPARTITION s6,
	SUBPARTITION s7,
	SUBPARTITION s8,
	SUBPARTITION s9,
	SUBPARTITION s10,
	SUBPARTITION s11
	),
	PARTITION t2 VALUES LESS THAN MAXVALUE
	(
	SUBPARTITION s12,
	SUBPARTITION s13,
	SUBPARTITION s14,
	SUBPARTITION s15,
	SUBPARTITION s16,
	SUBPARTITION s17
	)
);


上述语句创建了三个按照RANGE划分的主分区,每个主分区下面有六个按照HASH划分的子分区。

插入测试数据:

INSERT INTO `msgss`(`sender`,`reciver`,`msg_type`,`msg`,`atime`,`sub_id`) VALUES(1,2,0,'Hello HASH',UNIX_TIMESTAMP(NOW()),1);
INSERT INTO `msgss`(`sender`,`reciver`,`msg_type`,`msg`,`atime`,`sub_id`) VALUES(1,2,0,'Hello HASH 2',UNIX_TIMESTAMP(NOW()),2);
INSERT INTO `msgss`(`sender`,`reciver`,`msg_type`,`msg`,`atime`,`sub_id`) VALUES(1,2,0,'Hello HASH 3',UNIX_TIMESTAMP(NOW()),3);
INSERT INTO `msgss`(`sender`,`reciver`,`msg_type`,`msg`,`atime`,`sub_id`) VALUES(1,2,0,'Hello HASH 10',UNIX_TIMESTAMP(NOW()),10);
INSERT INTO `msgss`(`sender`,`reciver`,`msg_type`,`msg`,`atime`,`sub_id`) VALUES(1,2,0,'Hello HASH 7',UNIX_TIMESTAMP(NOW()),7);
INSERT INTO `msgss`(`sender`,`reciver`,`msg_type`,`msg`,`atime`,`sub_id`) VALUES(1,2,0,'Hello HASH 5',UNIX_TIMESTAMP(NOW()),5);

INSERT INTO `msgss`(`sender`,`reciver`,`msg_type`,`msg`,`atime`,`sub_id`) VALUES(1,2,0,'Hello HASH',1451577607,1);
INSERT INTO `msgss`(`sender`,`reciver`,`msg_type`,`msg`,`atime`,`sub_id`) VALUES(1,2,0,'Hello HASH 2',1451577609,2);
INSERT INTO `msgss`(`sender`,`reciver`,`msg_type`,`msg`,`atime`,`sub_id`) VALUES(1,2,0,'Hello HASH 3',1451577623,3);
INSERT INTO `msgss`(`sender`,`reciver`,`msg_type`,`msg`,`atime`,`sub_id`) VALUES(1,2,0,'Hello HASH 10',1451577654,10);
INSERT INTO `msgss`(`sender`,`reciver`,`msg_type`,`msg`,`atime`,`sub_id`) VALUES(1,2,0,'Hello HASH 7',1451577687,7);
INSERT INTO `msgss`(`sender`,`reciver`,`msg_type`,`msg`,`atime`,`sub_id`) VALUES(1,2,0,'Hello HASH 5',1451577699,5);

INSERT INTO `msgss`(`sender`,`reciver`,`msg_type`,`msg`,`atime`,`sub_id`) VALUES(1,2,0,'Hello HASH',1514736056,1);
INSERT INTO `msgss`(`sender`,`reciver`,`msg_type`,`msg`,`atime`,`sub_id`) VALUES(1,2,0,'Hello HASH 2',1514736066,2);
INSERT INTO `msgss`(`sender`,`reciver`,`msg_type`,`msg`,`atime`,`sub_id`) VALUES(1,2,0,'Hello HASH 3',1514736076,3);
INSERT INTO `msgss`(`sender`,`reciver`,`msg_type`,`msg`,`atime`,`sub_id`) VALUES(1,2,0,'Hello HASH 10',1514736086,10);
INSERT INTO `msgss`(`sender`,`reciver`,`msg_type`,`msg`,`atime`,`sub_id`) VALUES(1,2,0,'Hello HASH 7',15147360,7);
INSERT INTO `msgss`(`sender`,`reciver`,`msg_type`,`msg`,`atime`,`sub_id`) VALUES(1,2,0,'Hello HASH 5',1514736098,5);

进行分区分析:

EXPLAIN PARTITIONS SELECT * FROM msgss;

可以检测到分区信息如下:

检测分区数据分布:

EXPLAIN PARTITIONS SELECT * FROM msgss WHERE `atime`<1451577600;

EXPLAIN PARTITIONS SELECT * FROM msgss WHERE `atime`>1451577600 AND `atime`<1483200000;

EXPLAIN PARTITIONS SELECT * FROM msgss WHERE `atime`>1483200000 AND `atime`<1514736000;

EXPLAIN PARTITIONS SELECT * FROM msgss WHERE `atime`>1514736000;

结果:第一条语句只扫描了t0的所有子分区,第二条语句只扫描了t1的所有子分区,第三四条分别只扫描了t2的所有子分区,证明表的分区和数据分布成功。

需求:目前已经是2017年,需要将2015年所有的聊天记录删除,但是保留2016年的聊天记录,并且2017年的数据也能正常按照分区进行存储。

实现以上需求,需要两步,第一步删除t0分区,第二步按照新规则重建分区。

删除分区语句:

ALTER TABLE `msgss` DROP PARTITION t0;

重建分区语句:

ALTER TABLE `msgss` PARTITION BY RANGE (atime) SUBPARTITION BY HASH (sub_id) 
(
	PARTITION t0 VALUES LESS THAN(1483200000)
	(
	SUBPARTITION s0,
	SUBPARTITION s1,
	SUBPARTITION s2,
	SUBPARTITION s3,
	SUBPARTITION s4,
	SUBPARTITION s5
	),
	PARTITION t1 VALUES LESS THAN(1514736000)
	(
	SUBPARTITION s6,
	SUBPARTITION s7,
	SUBPARTITION s8,
	SUBPARTITION s9,
	SUBPARTITION s10,
	SUBPARTITION s11
	),
	PARTITION t2 VALUES LESS THAN MAXVALUE
	(
	SUBPARTITION s12,
	SUBPARTITION s13,
	SUBPARTITION s14,
	SUBPARTITION s15,
	SUBPARTITION s16,
	SUBPARTITION s17
	)
);

查询发现,15年的数据全部被删除,剩余的数据被重新分区并分布。

下载本文
显示全文
专题