mysql 分区-子分区(七)

子分区

子分区(subpartition):是分区表中对每个分区的再次分割,又被称为复合分区,目前只有RANGE和LIST分区的表可以再进行子分区,子分区只能是HASH或者KEY分区。复合分区适用于保存非常大量的数据记录。

子分区由两种创建方法:
一种是不定义每个子分区子分区的名字和路径由分区决定,
二是定义每个子分区的分区名和各自的路径。

【注意:由于分区是RANGE和LIST分区,所以删除分区也是同RANGE和LIST分区一样,这里只能对每个分区进行删除,不能针对每个子分区进行删除或添加操作,删除分区后子分区连同数据一并被删除。】

语法1(不定义每个子分区子分区的名字和路径):

create table  (
	// 字段
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1
partition by range (分区字段)
SUBPARTITION BY HASH(分区字段)
SUBPARTITIONS NUM(
	partition <分区名称> values less than (Value),
  	partition <分区名称> values less than (Value),
  	...
    partition <分区名称> values less than maxvalue
)

分区字段:表示要按照哪个字段进行分区,可以是一个字段名,也可以是对某个字段进行表达式运算如year(create_time),使用range最终的值必须是数字
分区名称: 要保证不同,也可以采用 p0、p1、p2 这样的分区名称,
less than : 表示小于
Value : 表示要小于某个具体的值,如 less than (10) 那么分区字段的值小于10的都会被分到这个分区
maxvalue: 表示一个最大的值
NUM:子分区数

demo1:
假如一个大型超市有40多家门店,该表保存40家超市的职员记录。这40家超市的的编号从1到40,如果你想将入职员工按年份区分同时还能精确到天区分,那么你可以采用range分区,创建的数据库表如下:

CREATE TABLE `employees_range_sub` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `ename` varchar(30) NOT NULL DEFAULT '' COMMENT '员工名称',
  `ecode` varchar(30) NOT NULL DEFAULT '' COMMENT '员工编号',
  `store_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '所属门店',
  `create_time` datetime DEFAULT '0000-00-00 00:00:00' COMMENT '添加时间',
  PRIMARY KEY (`id`,`create_time`)
)  ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='员工表'
partition by range(year(create_time))
subpartition BY HASH (to_days(create_time))
subpartitions 2(
	partition f0 values less than (2018),
	partition f1 values less than (2019),
	partition f2 values less than MAXVALUE
)

分区文件(截图):
mysql 分区-子分区(七)_第1张图片
通过sql方式查看分区情况:

格式:
SELECT PARTITION_NAME,PARTITION_METHOD,PARTITION_EXPRESSION,
PARTITION_DESCRIPTION,TABLE_ROWS,SUBPARTITION_NAME,
SUBPARTITION_METHOD,SUBPARTITION_EXPRESSION 
FROM information_schema.PARTITIONS
 WHERE 
 TABLE_SCHEMA=SCHEMA() 
 AND TABLE_NAME='tablename';

#demo
SELECT PARTITION_NAME,PARTITION_METHOD,PARTITION_EXPRESSION,
PARTITION_DESCRIPTION,TABLE_ROWS,SUBPARTITION_NAME,
SUBPARTITION_METHOD,SUBPARTITION_EXPRESSION 
FROM information_schema.PARTITIONS
 WHERE 
 TABLE_SCHEMA=SCHEMA() 
 AND TABLE_NAME='employees_range_sub';

mysql 分区-子分区(七)_第2张图片1.重置分区(只能对每个分区进行操作,不能针对每个子分区进行删除或添加操作)

alter table employees_range_sub 
REORGANIZE partition f0,f1,f2 INTO
(
		partition f0 values less than (2018),
		partition f1 values less than (2019),
		partition f2 values less than (2020),
		partition f3 values less than MAXVALUE
)

2.拆分分区/重置分区(子分区重新命名/拆分子分区)

alter table employees_range_sub 
REORGANIZE partition f0,f1,f2 INTO
(
		partition f0 values less than (2018)(
			subpartition s0,
			subpartition s1
		),
		partition f1 values less than (2019)(
			subpartition s2,
			subpartition s3
		),
		partition f2 values less than (2020)(
			subpartition s4,
			subpartition s5
		),
		partition f3 values less than MAXVALUE(
			subpartition s6,
			subpartition s7
		)
)

#注意:创建分区的时候子分区就是2,所以子分区不能新建或删减
mysql 分区-子分区(七)_第3张图片

分区文件(截图):
mysql 分区-子分区(七)_第4张图片
3.删除分区(只能对每个分区进行操作,不能针对每个子分区进行删除或添加操作)

alter table employees_range_sub drop partition f3;

语法2(定义每个子分区的分区名):

create table 
( // 字段 ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 partition by range (分区字段) SUBPARTITION BY HASH(分区字段) SUBPARTITIONS NUM( partition <分区名称> values less than (Value)( subpartition <子分区名称>, subpartition <子分区名称> ), partition <分区名称> values less than (Value)( subpartition <子分区名称>, subpartition <子分区名称> ), ... partition <分区名称> values less than maxvalue( subpartition <子分区名称>, subpartition <子分区名称> ) ) 分区字段:表示要按照哪个字段进行分区,可以是一个字段名,也可以是对某个字段进行表达式运算如year(create_time),使用range最终的值必须是数字 分区名称: 要保证不同,也可以采用 p0、p1、p2 这样的分区名称, 子分区名称: 要保证不同,也可以采用 s0、s1、s2 这样的子分区名称,子分区的名称不能喝分区名称重复 less than : 表示小于 Value : 表示要小于某个具体的值,如 less than (10) 那么分区字段的值小于10的都会被分到这个分区 maxvalue: 表示一个最大的值

demo1:
假如一个大型超市有40多家门店,该表保存40家超市的职员记录。这40家超市的的编号从1到40,如果你想将入职员工按年份区分同时还能精确到天区分,那么你可以采用range分区,创建的数据库表如下:

CREATE TABLE `employees_range_sub_name` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `ename` varchar(30) NOT NULL DEFAULT '' COMMENT '员工名称',
  `ecode` varchar(30) NOT NULL DEFAULT '' COMMENT '员工编号',
  `store_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '所属门店',
  `create_time` datetime DEFAULT '0000-00-00 00:00:00' COMMENT '添加时间',
  PRIMARY KEY (`id`,`create_time`)
)  ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='员工表'
partition by range(year(create_time))
subpartition BY HASH (to_days(create_time))
(
	partition f0 values less than (2018)(
		subpartition f0s0,
		subpartition f0s1
	),
	partition f1 values less than (2019)(
			subpartition f1s0,
			subpartition f1s1
	),
	partition f2 values less than (2020)(
			subpartition f2s0,
			subpartition f2s1
	)
);

分区文件(截图):
mysql 分区-子分区(七)_第5张图片
1.添加分区和子分区(只能对每个分区进行操作,不能针对每个子分区进行删除或添加操作)

alter table employees_range_sub_name add partition
(
	partition f3 values less than (2021)(
			subpartition f3s0,
			subpartition f3s1
	)
)

2.重置分区,重置子分区(只能对每个分区进行操作,不能针对每个子分区进行删除或添加操作)

alter table employees_range_sub_name
REORGANIZE partition f0,f1,f2,f3 into(
	partition f1 values less than (2019)(
			subpartition f1s0,
			subpartition f1s1
	),
	partition f2 values less than (2020)(
			subpartition f2s0,
			subpartition f2s1
	),
	partition f3 values less than MAXVALUE(
			subpartition f3s0,
			subpartition f3s1
	)
)

注意:重置的时候子分区的数量不能添加货减少,只能重命名
mysql 分区-子分区(七)_第6张图片
3.删除分区(只能对每个分区进行操作,不能针对每个子分区进行删除或添加操作)

alter table employees_range_sub_name drop partition f3;

你可能感兴趣的:(mysql)