MySQL表分区

MySQL表分区

表分区介绍

MySQL 数据库中的数据是以文件的形势存在磁盘上的,

默认放在 /var/lib/mysql/ 目录下面,

我们可以通过 show variables like '%datadir%'; 命令来查看:

sql 复制代码
show variables like '%datadir%';

我们进入到这个目录下,就可以看到我们定义的所有数据库了,

一个数据库就是一个目录,一个库中,有其对应的表的信息,如下:

bash 复制代码
cd /var/lib/mysql
bash 复制代码
ls

优点:

  1. 查询性能提升:分区可以将大表划分为更小的部分,查询时只需扫描特定的分区,而不是整个表,从而提高查询性能。特别是在处理大量数据或高并发负载时,分区可以显著减少查询的响应时间。
  2. 管理和维护的简化:使用分区可以更轻松地管理和维护数据。可以针对特定的分区执行维护操作,如备份、恢复、优化和数据清理,而不必处理整个表。这简化了维护任务并减少了操作的复杂性。
  3. 数据管理灵活性:通过分区,可以根据业务需求轻松地添加或删除分区,而无需影响整个表。这使得数据的增长和变化更具弹性,可以根据需求进行动态调整。
  4. 改善数据安全性和可用性:可以将不同分区的数据分布在不同的存储设备上,从而提高数据的安全性和可用性。例如,可以将热数据放在高速存储设备上,而将冷数据放在廉价存储设备上,以实现更高的性能和成本效益。

缺点:

  1. 复杂性增加:分区引入了额外的复杂性,包括分区策略的选择、表结构的设计和维护、查询逻辑的调整等。正确地设置和管理分区需要一定的经验和专业知识。
  2. 索引效率下降:对于某些查询,特别是涉及跨分区的查询,可能会导致索引效率下降。由于查询需要在多个分区之间进行扫描,可能无法充分利用索引优势,从而影响查询性能。
  3. 存储空间需求增加:使用分区会导致一定程度的存储空间浪费。每个分区都需要占用一定的存储空间,包括分区元数据和一些额外的开销。因此,对于分区键的选择和分区粒度的设置需要权衡存储空间和性能之间的关系。
  4. 功能限制:在某些情况下,分区可能会限制某些MySQL的功能和特性的使用。例如,某些类型的索引可能无法在分区表上使用,或者某些DDL操作可能需要更复杂的处理。

在考虑使用分区时,需要综合考虑业务需求、查询模式、数据规模和硬件资源等因素,

并权衡分区带来的优势和缺点。对于特定的应用和数据场景,

分区可能是一个有效的解决方案,但并不适用于所有情况。

同时分区表也存在一些限制,如下:

限制:

  • 在mysql5.6.7之前的版本,一个表最多有1024个分区;从5.6.7开始,一个表最多可以有8192个分区。
  • 分区表无法使用外键约束。
  • NULL值会使分区过滤无效。
  • 所有分区必须使用相同的存储引擎。

分区适用场景

分区表在以下情况下可以发挥其优势,适用于以下几种使用场景:

  1. 大型表处理:当面对非常大的表时,分区表可以提高查询性能。通过将表分割为更小的分区,查询操作只需要处理特定的分区,从而减少扫描的数据量,提高查询效率。这在处理日志数据、历史数据或其他需要大量存储和高性能查询的场景中非常有用。
  2. 时间范围查询:对于按时间排序的数据,分区表可以按照时间范围进行分区,每个分区包含特定时间段内的数据。这使得按时间范围进行查询变得更高效,例如在某个时间段内检索数据、生成报表或执行时间段的聚合操作。
  3. 数据归档和数据保留:分区表可用于数据归档和数据保留的需求。旧数据可以归档到单独的分区中,并将其存储在低成本的存储介质上。同时,可以保留较新数据在高性能的存储介质上,以便快速查询和操作。
  4. 并行查询和负载均衡:通过哈希分区或键分区,可以将数据均匀地分布在多个分区中,从而实现并行查询和负载均衡。查询可以同时在多个分区上进行,并在最终合并结果,提高查询性能和系统吞吐量。
  5. 数据删除和维护:使用分区表,可以更轻松地删除或清理不再需要的数据。通过删除整个分区,可以更快速地删除大量数据,而不会影响整个表的操作。此外,可以针对特定分区执行维护任务,如重新构建索引、备份和优化,以减少对整个表的影响。

分区表并非适用于所有情况。在选择使用分区表时,需要综合考虑数据量、查询模式、存储资源和硬件能力等因素,并评估分区对性能和管理的影响。

分区策略

  1. RANGE分区

RANGE分区

RANGE分区是MySQL中的一种分区策略,根据某一列的范围值将数据分布到不同的分区。

每个分区包含特定的范围。下面是RANGE分区的定义方式、特点以及代码示例。

定义方式:

  1. 指定分区键:选择作为分区依据的列作为分区键,通常是日期、数值等具有范围特性的列。
  2. 分区函数:通过PARTITION BY RANGE指定使用RANGE分区策略。
  3. 定义分区范围:使用VALUES LESS THAN子句定义每个分区的范围。

RANGE分区的特点:

  1. 范围划分:根据指定列的范围进行分区,适用于需要按范围进行查询和管理的情况。
  2. 灵活的范围定义:可以定义任意数量的分区,并且每个分区可以具有不同的范围。
  3. 高效查询:根据查询条件的范围,MySQL能够快速定位到特定的分区,提高查询效率。
  4. 动态管理:可以根据业务需求轻松添加或删除分区,适应数据增长或变更的需求。

以下是一个使用RANGE分区的代码示例:

mysql 复制代码
create table sale(
	sale_id int,
    sale_date date,
    amount decimal(10,2)
) partition by range(year(sale_date))(
    partition p0 values less than (2020),
    partition p1 values less than (2021),
    partition p2 values less than (2022),
    partition p3 values less than (2023),
    partition p4 values less than (2024),
    partition p5 values less than (2025)
);
sql 复制代码
insert into sale values (1,'2020-11-11',9999.00);
insert into sale values (2,'2020-12-12',6666.00);
insert into sale values (3,'2021-11-11',12000.00);
insert into sale values (4,'2021-12-12',13000.00);
insert into sale values (5,'2022-11-11',13000.00);
insert into sale values (6,'2022-12-12',12500.00);
insert into sale values (7,'2023-11-11',12500.00);
insert into sale values (8,'2023-12-12',13000.00);
sql 复制代码
select * from sale partition(p0);
select * from sale partition(p1);

LIST分区

LIST分区是根据某一列的离散值将数据分布到不同的分区。每个分区包含特定的列值列表。下面是LIST分区的定义方式、特点以及代码示例。

定义方式:

  1. 指定分区键:选择作为分区依据的列作为分区键,通常是具有离散值的列,如地区、类别等。
  2. 分区函数:通过PARTITION BY LIST指定使用LIST分区策略。
  3. 定义分区列表:使用VALUES IN子句定义每个分区包含的列值列表。

LIST分区的特点:

  1. 列值离散:根据指定列的具体取值进行分区,适用于具有离散值的列。
  2. 灵活的分区定义:可以定义任意数量的分区,并且每个分区可以具有不同的列值列表。
  3. 高效查询:根据查询条件的列值直接定位到特定分区,提高查询效率。
  4. 动态管理:可以根据业务需求轻松添加或删除分区,适应数据增长或变更的需求。

以下是一个使用LIST分区的代码示例:

mysql 复制代码
create table people(
	id_card varchar(18),
    name varchar(50),
    province int
) partition by list(province)(
    partition huabei values in (11,12,13,14,15),
    partition dongbei values in (21,22,23),
    partition huazhong values in (31,32,33,34,35,36,37),
    partition huadong values in (41,42,43,44,45,46),
    partition xinan values in (50,51,52,53,55),
    partition xibei values in (61,62,63,64,65),
    partition gang_ao_tai values in (71,81,91)
);
sql 复制代码
insert into people values ('410182198903224674','邱赣',41);
insert into people values ('411429199211019071','何天',41);
insert into people values ('310182198903224674','方加牡',31);
insert into people values ('210182198903224674','贺巧',21);
insert into people values ('110182198903224674','闾丘饱乾',11);
insert into people values ('510182198903224674','丁经',51);
insert into people values ('610182198903224674','韦散',61);
insert into people values ('710182198903224674','东方让',71);
insert into people values ('810182198903224674','赖队瞻',81);
insert into people values ('910182198903224674','郭叹',91);
insert into people values ('120182198903224674','慕容芋岛',12);
insert into people values ('220182198903224674','孙劣',22);
insert into people values ('320182198903224674','王桃',32);
insert into people values ('420182198903224674','郝郑惭',42);
insert into people values ('520182198903224674','余烂',52);
insert into people values ('620182198903224674','宇文酚',62);
sql 复制代码
select * from people partition(huabei);
select * from people partition(dongbei);
select * from people partition(huazhong);
select * from people partition(huadong);
select * from people partition(xibei);
select * from people partition(gang_ao_tai);

HASH分区

HASH分区是使用哈希算法将数据均匀地分布到多个分区中。下面是HASH分区的定义方式、特点以及代码示例。

定义方式:

  1. 指定分区键:选择作为分区依据的列作为分区键。
  2. 分区函数:通过PARTITION BY HASH指定使用HASH分区策略。
  3. 定义分区数量:使用PARTITIONS关键字指定分区的数量。

HASH分区的特点:

  1. 数据均匀分布:HASH分区使用哈希算法将数据均匀地分布到不同的分区中,确保数据在各个分区之间平衡。
  2. 并行查询性能:通过将数据分散到多个分区,HASH分区可以提高并行查询的性能,多个查询可以同时在不同分区上执行。
  3. 简化管理:HASH分区使得数据管理更加灵活,可以轻松地添加或删除分区,以适应数据增长或变更的需求。

以下是一个使用HASH分区的代码示例:

sql 复制代码
create table user (
    id int auto_increment,
    name varchar(50),
    primary key (id)
)
 partition by hash (id)
 partitions 4;
sql 复制代码
insert into user (name) values ('邱赣');
insert into user (name) values ('何天');
insert into user (name) values ('方加牡');
insert into user (name) values ('贺巧');
insert into user (name) values ('闾丘饱乾');
insert into user (name) values ('丁经');
insert into user (name) values ('韦散');
insert into user (name) values ('东方让');
insert into user (name) values ('赖队瞻');
insert into user (name) values ('郭叹');
insert into user (name) values ('慕容芋岛');
insert into user (name) values ('孙劣');
insert into user (name) values ('王桃');
insert into user (name) values ('郝郑惭');
insert into user (name) values ('余烂');
insert into user (name) values ('宇文酚');
sql 复制代码
select * from user;
sql 复制代码
select * from user partition(p0);
sql 复制代码
select * from user partition(p1);
sql 复制代码
select * from user partition(p2);
sql 复制代码
select * from user partition(p3);

KEY分区

KEY分区是根据某一列的哈希值将数据分布到不同的分区。不同于HASH分区,KEY分区使用的是列值的哈希值而不是哈希函数。下面是KEY分区的定义方式、特点以及代码示例。

定义方式:

  1. 指定分区键:选择作为分区依据的列作为分区键。
  2. 分区函数:通过PARTITION BY KEY指定使用KEY分区策略。
  3. 定义分区数量:使用PARTITIONS关键字指定分区的数量。

KEY分区的特点:

  1. 哈希分布:KEY分区使用列值的哈希值将数据分布到不同的分区中,与哈希函数不同,它使用的是列值的哈希值。
  2. 高度自定义:KEY分区允许根据业务需求自定义分区逻辑,可以灵活地选择分区键和分区数量。
  3. 并行查询性能:通过将数据分散到多个分区,KEY分区可以提高并行查询的性能,多个查询可以同时在不同分区上执行。
  4. 简化管理:KEY分区使得数据管理更加灵活,可以轻松地添加或删除分区,以适应数据增长或变更的需求。

以下是一个使用KEY分区的代码示例:

sql 复制代码
create table person (
    id int auto_increment,
    name varchar(50),
    primary key (id)
)
 partition by key(id)
 partitions 4;
sql 复制代码
insert into person (name) values ('邱赣');
insert into person (name) values ('何天');
insert into person (name) values ('方加牡');
insert into person (name) values ('贺巧');
insert into person (name) values ('闾丘饱乾');
insert into person (name) values ('丁经');
insert into person (name) values ('韦散');
insert into person (name) values ('东方让');
insert into person (name) values ('赖队瞻');
insert into person (name) values ('郭叹');
insert into person (name) values ('慕容芋岛');
insert into person (name) values ('孙劣');
insert into person (name) values ('王桃');
insert into person (name) values ('郝郑惭');
insert into person (name) values ('余烂');
insert into person (name) values ('宇文酚');
sql 复制代码
select * from person;
sql 复制代码
select * from person partition(p0);
sql 复制代码
select * from person partition(p1);
sql 复制代码
select * from person partition(p2);
sql 复制代码
select * from person partition(p3);

COLUMNS 分区

MySQL在5.5版本引入了COLUMNS分区类型,其中包括RANGE COLUMNS分区和LIST COLUMNS分区。以下是对这两种COLUMNS分区的详细说明:

  1. RANGE COLUMNS分区: RANGE COLUMNS分区是根据列的范围值将数据分布到不同的分区的分区策略。它类似于RANGE分区,但是根据多个列的范围值进行分区,而不是只根据一个列。这使得范围的定义更加灵活,可以基于多个列的组合来进行分区。

    下面是一个RANGE COLUMNS分区的代码示例:

    sql 复制代码
    create table product(
        product_id int,
        product_name varchar(50),
        product_location int,
        category_id int
    ) partition by range columns(category_id,product_location)(
        partition p11 values less than (1,1),
        partition p12 values less than (1,2),
        partition p21 values less than (2,1),
        partition p22 values less than (2,2)
    );

    每个分区根据这两列的范围值进行划分。

  2. LIST COLUMNS分区: LIST COLUMNS分区是根据列的离散值将数据分布到不同的分区的分区策略。它类似于LIST分区,但是根据多个列的离散值进行分区,而不是只根据一个列。这使得离散值的定义更加灵活,可以基于多个列的组合来进行分区。

    下面是一个LIST COLUMNS分区的代码示例:

    sql 复制代码
    create table product(
        product_id int,
        product_name varchar(50),
        product_location int,
        category_id int
    ) partition by list columns(category_id,product_location)(
        partition p12 values in ((1,1),(1,2)),
        partition p22 values in ((2,1),(2,2))
    );

常见分区命令

向分区表添加新的分区

sql 复制代码
alter table sale add partition (partition p6 values less than (2026));

删除指定的分区

sql 复制代码
alter table sale drop partition p6;

重新组织分区

sql 复制代码
alter table sale REORGANIZE PARTITION p0, p1, p2,p3, p4, p5 INTO (
    partition p0 values less than (2021),
    partition p1 values less than (2023),
    partition p2 values less than (2025)
);

合并相邻的分区

sql 复制代码

分析指定分区的统计信息

sql 复制代码
alter table sale analyze partition p0;
相关推荐
tatasix39 分钟前
MySQL UPDATE语句执行链路解析
数据库·mysql
南城花随雪。1 小时前
硬盘(HDD)与固态硬盘(SSD)详细解读
数据库
儿时可乖了1 小时前
使用 Java 操作 SQLite 数据库
java·数据库·sqlite
懒是一种态度1 小时前
Golang 调用 mongodb 的函数
数据库·mongodb·golang
天海华兮1 小时前
mysql 去重 补全 取出重复 变量 函数 和存储过程
数据库·mysql
gma9992 小时前
Etcd 框架
数据库·etcd
爱吃青椒不爱吃西红柿‍️2 小时前
华为ASP与CSP是什么?
服务器·前端·数据库
Yz98762 小时前
hive的存储格式
大数据·数据库·数据仓库·hive·hadoop·数据库开发
武子康3 小时前
大数据-231 离线数仓 - DWS 层、ADS 层的创建 Hive 执行脚本
java·大数据·数据仓库·hive·hadoop·mysql
黑色叉腰丶大魔王3 小时前
《MySQL 数据库备份与恢复》
mysql