欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 锐评 > 03、MySQL第二章,数据库分区

03、MySQL第二章,数据库分区

2025/5/3 13:31:52 来源:https://blog.csdn.net/pilot_speed/article/details/145450859  浏览:    关键词:03、MySQL第二章,数据库分区

MySql第二章,数据库分区

一、分区概述

数据分区是一种物理数据库的设计技术,它的目的是为了在特定的SQL操作中减少数据读写的总量以缩减响应时间。

分区并不是生成新的数据表,而是将表的数据均衡分摊到不同的硬盘,实际上还是一张表。另外,分区可以做到将表的数据均衡到不同的地方,提高数据检索的效率,降低数据库的频繁IO压力值 。

1、水平分区

这种形式分区是对表的行进行分区,通过这样的方式不同分组里面的物理列分割的数据集得以组合,从而进行个体分割(单分区)或集体分割(1个或多个分区)。所有在表中定义的列在每个数据集中都能找到,所以表的特性依然得以保持。

举个简单例子:一个包含十年发票记录的表可以被分区为十个不同的分区,每个分区包含的是其中一年的记录。

:这里具体使用的分区方式我们后面再说,可以先说一点,一定要通过某个属性列来分割,譬如这里使用的列就是年份。

2、垂直分区

这种分区方式一般来说是通过对表的垂直划分来减少目标表的宽度,使某些特定的列被划分到特定的分区,每个分区都包含了其中的列所对应的行。

举个简单例子:一个包含了大text和BLOB列的表,这些text和BLOB列又不经常被访问,这时候就要把这些不经常使用的text和BLOB了划分到另一个分区,在保证它们数据相关性的同时还能提高访问速度。

在数据库供应商开始在他们的数据库引擎中建立分区(主要是水平分区)时,DBA和建模者必须设计好表的物理分区结构,不要保存冗余的数据(不同表中同时都包含父表中的数据)或相互联结成一个逻辑父对象(通常是视图)。这种做法会使水平分区的大部分功能失效,有时候也会对垂直分区产生影响。

3、分区的优点

1、数据分割,放置于不同的物理文件中2、存储更多的数据,突破单个文件存储的最大限度3、精准定位分区查询数据,不需要全表扫描查询,大大提高数据检索效率4、数据管理比较方便,比如要清理或废弃某年的数据,就可以直接删除该日期的分区数据即可5、可跨磁盘分区查询,提高磁盘的I/O性能6、SUM()和COUNT()等聚合函数查询,可以更容易的进行并行处理7、可备份和恢复独立的分区

二、分区类型

1>、range  => 连续区间的列值:如0~99、100~1992>、list   => 类似range,离散集合:如[1,3,5,7,9]、[2,4,6,8,10]3>、hash   => 根据哈希函数分配,用户可自定义表达式。确保数据在预先确定数目的分区中平均分布4>、key    => 类似hash,但是由MySQL自身提供的函数

注:

1、若表存在 primary key 【PK】或 unique key【UK】,分区函数列只能从PK或UK中取子集。若无PK和UK,则可随意指定列作为分区列。2、MySQL-5.5version以前分区键必须为整型如int,5.5以后支持非整型3、InnoDB支持分区。MyISAM mysql8以前支持,之后不再支持了。

查看数据库是否支持分区:

5.6版本以后使用如下:show plugins;
结果:
partition ACTIVE  即支持分区

三、分区创建

1、range分区(常用)

CREATE TABLE `shop_user_info` (`user_info_id` bigint(30) NOT NULL COMMENT '主键ID',`user_code` varchar(64) NOT NULL COMMENT '用户编码',`user_name` varchar(100) NOT NULL COMMENT '用户名称',`gender` int(2) DEFAULT NULL COMMENT '性别 1:女 2:男 3:保密',`age` int(3) DEFAULT NULL COMMENT '年龄',`create_time` timestamp NULL DEFAULT NULL COMMENT '信息创建时间',`update_time` timestamp NULL DEFAULT NULL COMMENT '信息修改时间'
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='电商用户信息表'PARTITION BY RANGE (user_info_id)(PARTITION P0 VALUES LESS THAN (5),PARTITION P1 VALUES LESS THAN (10),PARTITION P2 VALUES LESS THAN (15),PARTITION P3 VALUES LESS THAN MAXVALUE
);

分区后默认的文件存放路径:

在这里插入图片描述

【自定义存放路径后面有写】

1.1、查看分区是否成功建立

show create table shop_user_info;

1.2、查询分区中的数据

select * from shop_user_info partition (p0);

1.3、查看数据所在分区

explain partitions select * from shop_user_info where user_info_id=1;

2、list分区(常用)

CREATE TABLE `shop_user_info2` (`user_info_id` bigint(30) NOT NULL COMMENT '主键ID',`user_code` varchar(64) NOT NULL COMMENT '用户编码',`user_name` varchar(100) NOT NULL COMMENT '用户名称',`gender` int(2) DEFAULT NULL COMMENT '性别 1:女 2:男 3:保密',`age` int(3) DEFAULT NULL COMMENT '年龄',`create_time` timestamp NULL DEFAULT NULL COMMENT '信息创建时间',`update_time` timestamp NULL DEFAULT NULL COMMENT '信息修改时间'
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='电商用户信息表'PARTITION BY list (user_info_id)(PARTITION P0 VALUES in (1,3,5,7,9),PARTITION P1 VALUES in (2,4,6,8,10)
);

注:

因为在上面 定义分区的时候,user_info_id设置了 1 3 5 7 9 2 4 6 8 10

所以user_info_id的值也只能在1 3 5 7 9 2 4 6 8 10中

##插入语句会操作失败
insert into shop_user_info2 value (66,'u66','name66',2,20,'2020-03-09 12:22:33','2020-03-09 12:25:55');

3、hash分区

【只支持整数分区】

【由于range和list分区无法保证数据的平均分布,所以有了hash分区和key分区】

CREATE TABLE `shop_user_info3` (`user_info_id` bigint(30) NOT NULL COMMENT '主键ID',`user_code` varchar(64) NOT NULL COMMENT '用户编码',`user_name` varchar(100) NOT NULL COMMENT '用户名称',`gender` int(2) DEFAULT NULL COMMENT '性别 1:女 2:男 3:保密',`age` int(3) DEFAULT NULL COMMENT '年龄',`create_time` timestamp NULL DEFAULT NULL COMMENT '信息创建时间',`update_time` timestamp NULL DEFAULT NULL COMMENT '信息修改时间'
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='电商用户信息表'PARTITION BY hash (user_info_id)
PARTITIONS 3;##这里数据会按  user_info_id % 3进行分配

注:

hash分区,数据的插入、更新、删除都会根据hash表达式计算一次选择分区,因此会有性能问题。

所以自定义表达式的时候尽量不要太复杂,最好为单列

4、linear hash 线性分区

partition by linear hash (id)
partition 3;

注:

线性分区在插入、更新、删除时性能会更好更快,但是数据会分布不均,所以一般不使用

5、key分区

key分区类似hash分区,但不允许自定义表达式,默认使用mysql自身提供的函数

可以分区除了支持整数分区外,还支持除了blob、text之外的分区

partition by linear key (id)
partition 3;

四、MySQL指定分区路径

MySQL可以针对分区表的每个分区指定各自的存储路径。

1、对于innodb存储引擎的表只能指定数据路径,因为数据和索引是存储在一个文件当中。2、对于MYISAM存储引擎可以分别指定数据文件和索引文件。3、一般也只有RANGE、LIST分区、sub子分区才有可能需要单独指定各个分区的路径,HASH和KEY分区的所有分区的路径都是一样。RANGE分区指定路径和LIST分区是一样的。 

1、MyISAM存储引擎

CREATE TABLE th (id INT, createDate DATE)
engine='MyISAM'PARTITION BY LIST(YEAR(createDate))
(PARTITION p0 VALUES IN (1995, 1999, 2003)DATA DIRECTORY = '/data/data'INDEX DIRECTORY = '/data/idx',PARTITION p1 VALUES IN (1996, 2000, 2004)DATA DIRECTORY = '/data/data'INDEX DIRECTORY = '/data/idx',PARTITION p2 VALUES IN (1997, 2001, 2005)DATA DIRECTORY = '/data/data'INDEX DIRECTORY = '/data/idx',PARTITION p3 VALUES IN (1998, 2002, 2006)DATA DIRECTORY = '/data/data'INDEX DIRECTORY = '/data/idx'
);

2、INNODB存储引擎

CREATE TABLE thex (id INT, createDate DATE)
engine='InnoDB'
PARTITION BY LIST(YEAR(createDate))
(PARTITION p0 VALUES IN (1995, 1999, 2003)DATA DIRECTORY = '/data/data',PARTITION p1 VALUES IN (1996, 2000, 2004)DATA DIRECTORY = '/data/data',PARTITION p2 VALUES IN (1997, 2001, 2005)DATA DIRECTORY = '/data/data',PARTITION p3 VALUES IN (1998, 2002, 2006)DATA DIRECTORY = '/data/data');

五、子分区

子分区:分区表中可以对每个分区再次切割,适合保存大量的数据。

range和hash组合:

CREATE TABLE `shop_user_info4` (`user_info_id` bigint(30) NOT NULL COMMENT '主键ID',`user_code` varchar(64) NOT NULL COMMENT '用户编码',`user_name` varchar(100) NOT NULL COMMENT '用户名称',`gender` int(2) DEFAULT NULL COMMENT '性别 1:女 2:男 3:保密',`age` int(3) DEFAULT NULL COMMENT '年龄',`create_time` datetime NULL DEFAULT NULL COMMENT '信息创建时间',`update_time` datetime NULL DEFAULT NULL COMMENT '信息修改时间'
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='电商用户信息表'partition by range (YEAR(create_time))
subpartition by hash (TO_DAYS(create_time))
subpartitions 2
(partition p0 values less than (2015),partition p1 values less than (2020),partition p2 values less than MAXVALUE
);

①、如果创建子分区,每一个分区必须有 相同数量 的子分区

②、对于已经通过range和list分区了的表,可再进行子分区。

​ 子分区既可以用hash分区,也可用key分区====> 我们称之为 复合分区

③、若指定分区名称,每一个分区和子分区的名称必须全局唯一

partition by range (YEAR(create_time))
subpartition by hash (TO_DAYS(create_time))
(partition p0 values less than (2015)(subpartition s0,subpartition s1),partition p1 values less than (2020)(subpartition s2,subpartition s3),partition p2 values less than MAXVALUE(subpartition s4,subpartition s5)
);

六、分区管理

分区管理即:对分区进行 添加、删除、重新定义、合并、拆分等操作

1、range和list分区

1.1、删除分区–数据丢失

alter table users drop partition p0;##数据会直接丢失
##list分区drop删除后,对应的删除值就不可再添加了

1.2、添加分区

alter table users add partition (partition p4 values less than (100));##range添加分区只能往高处添加,不能删除了p0再添加p0.
##有MAXVALUE的,先把MAXVALUE所在的分区删除后,再添加新的.##list分区,不能添加已存在的值

1.3、重新定义–数据不丢失

拆分p1分区

alter table users reorganize partition p1 into(partition s0 values less than (5),partition s1 values less than (10)
);

合并s0、s1分区

alter table users reorganize partition s0,s1 into(partition p0 less than (10)
);

1.4、删除所有分区–保留数据

alter table users remove partitioning;

2、hash和key分区

【hash和key分区只能减少或增加分区数量,数据不会丢失】

减少分区数:

alter table users coalesce partition 1;  ##减少1个分区

添加分区数:

alter table users add partition partitions 2;  ##添加2个分区

3、重建分区

alter table users rebuild partition p2,p3;##先删除分区中的记录,然后再重新插入。可用于整理分区碎片

4、分析分区

alter table users analyze partition p2,p3;##读取并保存分区键分布

5、检查分区

alter table users check partition p2,p3;##检查分区中的数据or索引是否被破坏

6、修补分区

alter table users repair partition p2,p3;##修补被破坏的分区

7、优化分区 = 分析+检查+修补分区

alter table users optimize partition p2,p3;##若删除大量行,优化后可收回没有使用的空间,并整理分区的碎片

七、注意事项

1、MySql分区处理NULL的方式

若分区键有的值为NULL,MySQL会默认将NULL视为0做处理,但这样数据就会分布不均匀,
所以我们在设计表和分区时尽量将分区列声明为 NOT NULL

2、注意

1、最大分区数不超过1024,一般建议不超过150个2、若有PK或UK,必须包含在分区键内3、不支持外键4、不支持全文索引,对分区表的分区键创建索引,那么这个索引也将被分区5、一般会按照 整数 or 日期 分区6、只有range和list可进行子分区,hash和key不可以7、临时表不能被分区8、分区表对单条记录的查询无优势9、注意分区成本(分区后数据的增删改性能会有影响)10、分区字段尽量不要使用NULL

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词