mysql分区之range分区

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介:
随着互联网的发展,各方面的数据越来越多,从最近两年大数据越来越强的呼声中就可见一斑。
我们所做的项目虽算不上什么大项目,但是由于业务量的问题,数据也是相当的多。
数据一多,就很容易出现性能问题,而为了解决这个问题我们通常很容易想到集群、分片等。
但是在某些时候却不一定必须要用集群、分片,也可以适当的使用数据分区。

什么是分区?
MySQL在未启用分区功能时,数据库的单个表内容是以单个文件的形式存放在文件系统上的。当启用分区功能后,MySQL将按用户指定的规则将单个表内容分割成几个文件存放在文件系统上。分区分为水平分区和垂直分区,水平分区是将表的数据按行分割成不同的数据文件,而垂直分区则是将表的数据按列分割成不同的数据文件。分片要遵循完备性原则、可重构性原则与不相交原则。完备性代表所有数据必须映射到某个片段上。可重构性表示所有分片数据必须可以重新构成全局数据。不相交性表示不同分片上的数据没有重复(除非你是特意做的冗余)。

大概是介于各方面的考虑,我们用的的表中就用到了range分区,数据库是其他人在管理,但是因为用到了这个表,因此我便抽时间进行了简单的学习。

据我的了解,要使用分区的话,必须要在创建表结构的时候就使用创建分区的语句,不能再后期更改。
例如我创建一个简单的emp表,有id、name、age三个字段,然后根据id分区。正确的建表语句基本如下:
CREATE TABLE emp(
id INT NOT NULL,
NAME VARCHAR(20),
age INT
)
PARTITION BY RANGE(ID)(
PARTITION p0 VALUES LESS THAN (6),
PARTITION p1 VALUES LESS THAN (11),
PARTITION pmax VALUES LESS THAN maxvalue
);
这里我是设置把整个表的数据分为三个区,id小于6的是一个区,区名称p0;id介于6到11的属于一个区,区名称p1;然后所有id大于11的一个区,区名称pmax。
整理一个语法,基本如下:
create table tablename(
字段名 数据类型
...
partition by range(分区依赖的字段名)(
partition 分取名 values less than (分区条件的值),
...
这里需要注意的是例子中的最后一行partition pmax values less than maxvalue,这一句中只有代表分区名的pmax是可以自己任意取得,剩下的单词不能变,maxvalue代表上边分区条件的最大值。
这样的话能保证所有数据都能正常入库,否则,假如没有这一句的话,那么id大于等于11的数据便无法存入库中,将会报错。

表结构创建好以后,为了测试分区是否成功,我向表中插入了一些数据,语句如下:
INSERT INTO emp VALUES(1,'test1',22);
INSERT INTO emp VALUES(2,'test2',25);
INSERT INTO emp VALUES(3,'test3',27);
INSERT INTO emp VALUES(4,'test4',20);
INSERT INTO emp VALUES(5,'test5',22);
INSERT INTO emp VALUES(6,'test6',25);
INSERT INTO emp VALUES(7,'test7',27);
INSERT INTO emp VALUES(8,'test8',20);
INSERT INTO emp VALUES(9,'test9',22);
INSERT INTO emp VALUES(10,'test10',25);
INSERT INTO emp VALUES(11,'test11',27);
INSERT INTO emp VALUES(12,'test12',20);
INSERT INTO emp VALUES(13,'test13',22);
INSERT INTO emp VALUES(14,'test14',25);
INSERT INTO emp VALUES(15,'test15',27);
INSERT INTO emp VALUES(16,'test16',20);
INSERT INTO emp VALUES(17,'test17',30);
INSERT INTO emp VALUES(18,'test18',40);
INSERT INTO emp VALUES(19,'test19',20);

数据插入完成后,要验证是否对应id的数据保存在了对应的分区,可以使用查询分区的命令,如下:
SELECT partition_name,partition_expression,partition_description,table_rows
FROM information_schema.PARTITIONS
WHERE table_schema = SCHEMA() AND table_name='emp'
查询出的结果如图:
967797e67c68c70559530790541c324cc1dce003
可以看出partition_name是分区名,partition_expression是分区依赖的字段,partition_description可以理解成该分区的条件,table_rows表示该分区中现在有的数据量。

从上边的数据中可以看出分区是成功的,但是如上分区虽然可以避免无法插入的问题,却又出现了一个新的问题。
那就是最后一个pmax区的数据有可能非常的大,这样一来,数据并不平均,不成比例,有可能使得查询最后一个区的数据时依旧出现性能问题。所以,解决办法大致有这样三个:

一是在能控制分区字段数据的情况下,比如说这里的id,假如能明确的知道什么时候会是多大的值,那么就可以一开始的时候不要这个pmax,而是定期的增加分区。例如这里存在了p0、p1,那么可以在id即将到达11的时候增加p2、p3甚至更多。增加分区的语句示例如下:
ALTER TABLE emp ADD PARTITION(PARTITION p2 VALUES LESS THAN (16))
语法整理就是:alter table tablename add partition(partition 分区名 values lessthan (分区条件))

上边这个办法可以解决数据不成比例的这个问题,只不过也同时存在隐患,那就是假如什么时候忘了增加后边的分区,亦或者说是分区依赖的字段值超出了预料,那么就又可能导致数据无法入库的问题。这样一来又有两种方法可以解决:
一是可以使用mysql的事务机制和存储过程等,做一个mysql的定时任务,然后使数据库系统自己在特定的时间增加分区。这样一来基本上不会出现第一个方法所说的问题,只不过这种方法需要对mysql的事务和存储过程也有一定的理解,操作起来有一定的难度。
我知道这个方法,暂时还没有着手去实现,等后边进一步了解事务和存储过程后再给出相关的例子。

那么除开上边这种定时任务的方法外,还有一个就是拆分分区的办法,也就是还是使用之前有pmax分区的这个表结构,然后用拆分分区的语句来拆分pmax。示例如下:
ALTER TABLE emp REORGANIZE PARTITION pmax INTO(
PARTITION p2 VALUES LESS THAN (16),
PARTITION pmax VALUES LESS THAN maxvalue
)
然后我们再用查询分区情况的语句查询,便可以看到结果变成这样:
9df1b7ee17d002927082bc19b5f9a2fddb547746
很显然,多出来了一个p2分区,拆分成功的同事不影响其他的功能。
那么这里分区拆分的语法整理如下:
alter table tablename reorganize partition 要拆分的分区名 into(
partition 拆分后的分区名1 values less than (条件),
partition 拆分后的分区名2 values lessthan (条件),
...
)

好了,到这里基本上算是完成了,但是我们知道数据库一般的操作都是增删改查,我们这里已经有了增改查,却自然也不能少了删。
按理说正常的生产环境的数据库应该是不能随意删除数据的,但是并不代表就不能删,反而有的时候还必须要删。
就比如我们项目中那个库,由于数据量太大,即便是分区了也依旧会在大量数据的情况下变慢。而与此同时,我们是按时间分区的,实际使用过程中只需要用到几天的数据,那么实际上很早以前的数据是可以删除不要的,或者说备份以后删除这个表的,这样就需要用到删除语句。
当然了,删除可以用delete,但是这样的话分区信息还在库中,实际上也是没必要要的,完全可以直接删除分区,因为删除分区的时候也同时会删除这个区内的所有数据。
示例之前我们先查一下之前插入的所有数据,如图:
f0b75785b66e1e70b24fc2b185be04ca72f0f2b8
这里示例删除p0分区代码如下:
ALTER TABLE emp DROP PARTITION p0
然后先用查询分区的代码看一下,如图
7069da1b203274e95da001432f91141548a3b862
可以看到p0区不见了,在select * 一下,如图:
3d1153a6342efec03aefd0bc24693fd1a065164b
可以看到id小于6的数据已经没有了,数据删除成功。
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
24天前
|
SQL 监控 关系型数据库
MySQL如何查看每个分区的数据量
通过本文的介绍,您可以使用MySQL的 `INFORMATION_SCHEMA`查询每个分区的数据量。了解分区数据量对数据库优化和管理具有重要意义,可以帮助您优化查询性能、平衡数据负载和监控数据库健康状况。希望本文对您在MySQL分区管理和性能优化方面有所帮助。
66 1
|
1月前
|
存储 关系型数据库 MySQL
MySQL 如何查看每个分区的数据量
MySQL 如何查看每个分区的数据量
30 3
|
6月前
|
缓存 关系型数据库 MySQL
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
294 0
|
4月前
|
DataWorks 安全 关系型数据库
DataWorks产品使用合集之如何实现MySQL数据库的自动分区
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
|
5月前
|
分布式计算 DataWorks 关系型数据库
DataWorks产品使用合集之当需要将数据从ODPS同步到RDS,且ODPS表是二级分区表时,如何同步所有二级分区的数据
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
64 7
|
5月前
|
存储 缓存 关系型数据库
心得经验总结:理解MySQL——并行数据库与分区(Partion)
心得经验总结:理解MySQL——并行数据库与分区(Partion)
44 0
|
6月前
|
存储 关系型数据库 MySQL
MySQL的优化利器⭐️Multi Range Read与Covering Index是如何优化回表的?
本文以小白的视角使用通俗易懂的流程图深入浅出分析Multi Range Read与Covering Index是如何优化回表
|
6月前
|
关系型数据库 MySQL 分布式数据库
PolarDB产品使用合集之PolarDB MySQL标准版中带有分区功能吗
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
6月前
|
SQL 关系型数据库 MySQL
mysql查询语句的访问方法const、ref、ref_or_null、range、index、all
mysql查询语句的访问方法const、ref、ref_or_null、range、index、all
|
6月前
|
存储 关系型数据库 MySQL
Mysql 分库分区分表
Mysql 分库分区分表

热门文章

最新文章

下一篇
无影云桌面