MySQL 表分区

MySQL 表分区

说明

在某些场景中,需要将表以一定的规律分割以达到优化效果。通常的做法是分表或者分区。分表是将一张表以 不同的规则分割( 水平分割或垂直分割 )成多张表。而分区与分表不同,分区只支持水平分区,表分区之后,从逻辑上来看仍是一张独立的表( 执行 SQL 时仍将其作为一张表来查询 ),而底层则是分为多个物理子表( 文件系统中表的每个分区都有各自的存储文件 )。

 

注意:

1、从 MySQL 5.7.17 开始,通用的分区处理程序( generic partitioning handler )将被弃用,并在 MySQL 8.0 中正式删除。而后由表的存储引擎提供自己的分区处理程序( native partitioning handler ),当前只有 InnoDB 和 NDB 存储引擎做到这一点。为了兼容 MySQL 8.0,需要将存储引擎修改为提供分区处理程序的引擎,如:

当然,在 MySQL 8.0 之前还是可以使用大部分存储引擎来实现分区的,除了 MERGE, CSV, 和 FEDERATED 存储引擎。另外不可以在同一张表中为各个分区指定不同的存储引擎。

2、NDB 存储引擎只支持通过 KEY 或 LINEAR KEY 进行分区

3、分区适用于表的所有数据和索引;不能只对数据进行分区而不对索引进行分区,反之亦然,也不能只对表的一部分进行分区

4、可以在 CREATE TABLE 语句中的分区子句使用 DATA DIRECTORY 和 INDEX DIRECTORY 来为数据和索引指定特定的目录。在 Windows 上,MyISAM 表的各个分区和子分区不支持这两个选项。对于InnoDB表的各个分区和子分区,则只支持 DATA DIRECTORY 选项。

5、表的分区表达式中使用的所有列必须是表可能具有的每个惟一键的一部分,包括任何主键

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

SHOW plugins;

分区类型

  • RANGE 分区:这一类型的分区根据给定范围的列值将行分配给分区
  • LIST 分区:类似于 RANGE 分区,只是该类型是根据与一组离散值之一匹配的列来进行选择的
  • HASH 分区:对于这种类型的分区,将根据用户定义的表达式返回的值来选择分区,该表达式对要插入到表中的行中的列值进行操作。该函数可以由 MySQL 中任何有效的表达式组成,表达式产生一个非负整数值。对这种类型的扩展 LINEAR HASH 也可用。
  • KEY 分区:这个类型的分区类似于 HASH 分区,除了提供一个或多个要计算的列之外,MySQL 还提供了自己的哈希函数。这些列可以包含整数之外的值,因为 MySQL 提供的哈希函数保证无论列的数据类型是什么,结果都是一个整数值。

务必要记住,无论使用的分区类型是什么,分区总是在创建时自动从 0 开始编号和排序。当新的一行插入到一个分区表中时,将使用这些分区号来标识正确的分区。比如,表使用了 4 个分区,则这些分区的编号为 0,1,2 和 3。对于 RANGE 和 LIST 类型的分区,有必要确保为每个分区号定义了一个分区。对于 HASH 分区类型,用户提供的表达式计算的整数值必须大于 0。对于 KEY 分区类型,将由 MySQL 提供的哈希函数自动处理。

CREATE TABLE `contents` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `key` char(32) NOT NULL DEFAULT '',
  `content` text,
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`,`key`),
  KEY `ckey` (`key`) USING HASH
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
/*!50100 PARTITION BY KEY (`key`)
PARTITIONS 127 */;

hash 分区值应当为素数

CREATE TABLE `contents` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `key` char(32) DEFAULT "",
  `content` text,
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`,`key`),
  KEY `key` (`key`) USING HASH
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 PARTITION BY key(`key`) PARTITIONS 127;

查看某一个key 所在的分区

select partition_name,partition_expression,partition_description,table_rows from information_schema.partitions where table_schema = schema() and table_name = "contents";

#create event hash_emp_event on SCHEDULE every 1 second do insert into HASH_EMP values (NULL,now());
set GLOBAL event_scheduler = 0;

explain partitions select * from contents where `key`="a317dda63ee7b5778afccd574c56c94d";

 

未经允许不得转载:微信 美文-微信文章库-我的知识库 » MySQL 表分区

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

我的知识库