分区
分区是指将一张表中的数据和索引分散存储到同一台计算机或不同计算机磁盘上的多个文件中。分区操作对于上层访问是透明的,用户访问MySQL中的分区表时,不必关心当前访问的数据存储到数据表的哪个分区中。对MySQL中的数据表进行分区也不会影响上层的业务逻辑。
查看是否支持分区操作
# 查看数据库是否支持分区操作
# MySQL 5.6以下版本
SHOW VARIABLES LIKE '%partition%';
# MySQL 5.7以上版本:partition显示ACTIVE
SHOW PLUGINS;
在MySQL 5.7及以下的版本中,支持使用大部分存储引擎创建分区表,例如可以使用MyISAM、InnoDB和Memory等存储引擎创建分区表,其他诸如MERGE、CSV等存储引擎不支持创建分区表。
在MySQL 5.1版本中,同一张数据表的所有分区必须使用同一个存储引擎,即一张数据表中不能对一个分区使用一种存储引擎,而对另一个分区使用其他存储引擎。
在MySQL 8.x版本中,MyISAM存储引擎已经不允许再创建分区表了,只能为实现了本地分区策略的存储引擎创建分区表,截至MySQL 8.0.18版本,只有InnoDB和NDB存储引擎支持创建分区表。
分区优势
分区表的优势:
- 存储更多的数据
- 优化查询:分区后,在WHERE条件语句中包含分区条件时,能够只扫描符合条件的一个或多个分区来查询数据,而不必扫描整个数据表中的数据,从而提高了数据查询的效率
- 并行处理:当查询语句中涉及SUM()、COUNT()、AVG()、MAX()和MIN()等聚合函数时,可以在每个分区上进行并行处理,再统计汇总每个分区得出的结果,从而得出最终的汇总结果数据,整体上提高了数据查询与统计的效率
- 快速删除数据:如果数据表中的数据已经过期,或者不需要再存储到数据表中,可以通过删除分区的方式快速删除数据表中的数据。删除分区比删除数据表中的数据在效率上要高得多
- 更大的数据吞吐量:分区后,能够跨多个磁盘分散数据查询,每个查询之间可以并行进行,能够获得更大的查询吞吐量,提升数据查询的性能
分区类型
在MySQL所有的分区类型中,进行分区的数据表可以不存在主键或者唯一键;如果存在主键或者唯一键,则不能使用主键或唯一键之外的其他字段进行分区操作。
MySQL的分区类型:
- RANGE分区:根据一个连续的区间范围,将数据分散存储于不同的分区,支持对字段名或表达式进行分区
- LIST分区:根据给定的值列表,将数据分散存储到不同的分区,支持对字段名或表达式进行分区
- HASH分区:根据给定的分区个数,结合一定的HASH算法,将数据分散存储到不同的分区,可以使用用户自定义的函数
- KEY分区:与HASH分区类似,但是只能使用MySQL自带的HASH函数
- COLUMNS分区:为解决MySQL 5.5版本之前RANGE分区和LIST分区只支持整数分区而在MySQL 5.5版本新引入的分区类型
- 子分区:对数据表中的每个分区再次进行分区
注意:RANGE分区与LIST分区有一定的相似性,RANGE分区是基于一个连续的区间范围分区,而LIST分区是基于一个给定的值列表进行分区;HASH分区与KEY分区类似,HASH分区既可以使用MySQL本身提供的HASH函数进行分区,也可以使用用户自定义的表达式分区,而KEY分区只能使用MySQL本身提供的函数进行分区。
RANGE分区
RANGE分区是根据连续不间断的取值范围进行分区,并且每个分区中的取值范围不能重叠,可以使用VALUES LESS THAN语句定义分区区间。
- 分区名称不区分大小写,即不能创建只有大小写不同的相同分区
CREATE TABLE t_members (
id INT NOT NULL,
first_name VARCHAR(30),
last_name VARCHAR(30),
join_date DATE NOT NULL DEFAULT '2020-01-01',
first_login_date DATE NOT NULL DEFAULT '2020-01-01',
group_code INT NOT NULL,
group_id INT NOT NULL
)
PARTITION BY RANGE (group_id)(
PARTITION part0 VALUES LESS THAN (10),
PARTITION part1 VALUES LESS THAN (20),
PARTITION part2 VALUES LESS THAN (30),
PARTITION part3 VALUES LESS THAN (40)
);
在MySQL中,可以通过查看information_schema数据库的partitions数据表来查看分区表的数据分布:
SELECT partition_name part, partition_expression expr,
partition_description part_desc, table_rows
FROM information_schema.partitions
WHERE table_schema = schema() AND table_name = 't_members';
在创建的分区表中,group_id字段的