绑定完请刷新页面
取消
刷新

分享好友

×
取消 复制
22.1 分区 介绍
2020-05-11 11:14:16

参考官方文档:

dev.mysql.com/doc/refma



注意:

从MySQL 5.7.17开始,MySQL服务器中的通用分区处理程序已被弃用,并且在MySQL 8.0中被删除,此时用于给定表的存储引擎应该提供其自己的(native)的分区区处理程序。 目前,只有InnoDB和NDB存储引擎才能这样做。


使用具有非native分区的表会导致ER_WARN_DEPRECATED_SYNTAX警告。 在MySQL 5.7.17到5.7.20中,服务器在启动时自动执行检查以识别使用非本地分区的表; 对于任何找到的,服务器会将消息写入其错误日志。 要禁用此检查,请使用--disable-partition-engine-check选项。 在MySQL 5.7.21及更高版本中,不执行此检查; 在这些版本中,如果希望服务器使用通用分区处理程序检查表,则必须使用--disable-partition-engine-check = false启动服务器(Bug#85830,Bug#25846957)。


要准备迁移到MySQL 8.0,应将任何具有非native分区的表更改为使用提供本机native的引擎,或者将其设置为非分区。 例如,要将表更改为InnoDB,请执行以下语句:

ALTER TABLE table_name ENGINE = INNODB;


您可以通过检查SHOW PLUGINS语句的输出来确定您的MySQL服务器是否支持分区,如下所示:

mysql> SHOW PLUGINS;

您还可以使用与此类似的查询检查INFORMATION_SCHEMA.PLUGINS表:

mysql> SELECT PLUGIN_NAME as Name, PLUGIN_VERSION as Version,PLUGIN_STATUS as Status FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_TYPE='STORAGE ENGINE'


在任何一种情况下,如果您没有看到输出中Status列的值为ACTIVE的分区插件,则表示不支持分区

如果要禁用分区支持,可以使用--skip-partition选项启动MySQL服务器。 禁用分区支持时,您可以查看任何现有的分区表并删除它们(尽管不建议这样做),但您无法以其他方式操纵它们或访问其数据。


22.1 MYSQL 分区概述


在MySQL中,InnoDB存储引擎长期以来一直支持表空间的概念,甚至在引入分区之前,MySQL服务器可以配置为使用不同的物理目录来存储不同的数据库。

通过使您能够根据您可以根据需要设置的规则在文件系统中分发单个表的各个部分,分区将这一概念更进一步。 实际上,表的不同部分作为单独的表存储在不同的位置。 用于完成数据划分的用户选择规则称为分区函数,其在MySQL中可以是模数,与一组范围或值列表的简单匹配,内部散列函数或线性散列函数。 根据用户指定的分区类型选择该函数,并将用户提供的表达式的值作为其参数。 此表达式可以是列值,作用于一个或多个列值的函数,或一组一个或多个列的值,具体取决于所使用的分区类型。

在RANGE,LIST和[LINEAR] HASH分区的情况下,分区列的值被传递给分区函数,该分区函数返回一个整数值,表示应该存储该特定记录的分区的编号。 此函数必须是非常量且非随机的。 它可能不包含任何查询,但可以使用在MySQL中有效的SQL表达式,只要该表达式返回NULL或整数intval,使得

-MAXVALUE <= intval <= MAXVALUE

(MAXVALUE用于表示所讨论的整数类型的小上限。-MAXVALUE表示大下限。)

对于[LINEAR] KEY,RANGE COLUMNS和LIST COLUMNS分区,分区表达式由一列或多列组成。


对于[LINEAR] KEY分区,分区函数由MySQL提供。

这就是所谓的水平分区,可以将表的不同行分配给不同的物理分区。 MySQL 5.7不支持垂直分区,其中表的不同列分配给不同的物理分区。 目前还没有计划将垂直分区引入MySQL。


要创建分区表,可以使用MySQL服务器支持的大多数存储引擎; MySQL分区引擎在一个单独的层中运行,可以与其中任何一个进行交互。 在MySQL 5.7中,同一分区表的所有分区必须使用相同的存储引擎; 例如,您不能将MyISAM用于一个分区而将InnoDB用于另一个分区。 但是,没有什么可以阻止您在同一MySQL服务器上甚至在同一数据库中为不同的分区表使用不同的存储引擎。

MySQL分区不能与MERGE,CSV或FEDERATED存储引擎一起使用。

使用NDB可以通过KEY或LINEAR KEY进行分区,但使用此存储引擎的表不支持其他类型的用户定义分区。 此外,使用用户定义分区的NDB表必须具有显式主键,并且表的分区表达式中引用的任何列都必须是主键的一部分。 但是,如果在用于创建或修改用户分区的NDB表的CREATE TABLE或ALTER TABLE语句的PARTITION BY KEY或PARTITION BY LINEAR KEY子句中未列出任何列,则表不需要具有显式主键。


要为分区表使用特定的存储引擎,只需使用[STORAGE] ENGINE选项,就像使用非分区表一样。 但是,您应该记住,需要在CREATE TABLE语句中使用任何分区选项之前,列出[STORAGE] ENGINE(和其他表选项)。 此示例显示如何创建一个通过散列分区为6个分区并使用InnoDB存储引擎的表:

CREATE TABLE ti (id INT, amount DECIMAL(7,2), tr_date DATE) ENGINE=INNODB PARTITION BY HASH( MONTH(tr_date) ) PARTITIONS 6;


每个PARTITION子句都可以包含[STORAGE] ENGINE选项,但在MySQL 5.7中这没有任何效果。



重要:

分区适用于表的所有数据和索引; 您不能只分区数据而不分区索引,反之亦然,也不能只分区表的一部分。

可以使用用于创建分区表的CREATE TABLE语句的PARTITION子句的DATA DIRECTORY和INDEX DIRECTORY选项将每个分区的数据和索引分配给特定目录。

Windows上的MyISAM表的各个分区或子分区不支持DATA DIRECTORY和INDEX DIRECTORY。

InnoDB表的各个分区和子分区仅支持DATA DIRECTORY选项。

表的分区表达式中使用的所有列必须是表可能具有的每个键的一部分,包括任何主键。 这意味着无法对以下SQL语句创建的此类表进行分区:

CREATE TABLE tnp ( id INT NOT NULL AUTO_INCREMENT, ref BIGINT NOT NULL, name VARCHAR(255), PRIMARY KEY pk (id), UNIQUE KEY uk (name) );


由于key pk和uk没有共同的列,因此没有可用于分区表达式的列。 在这种情况下可能的解决方法包括将name列添加到表的主键,将id列添加到uk,或者只是简单地删除键


此外,MAX_ROWS和MIN_ROWS可用于分别确定可存储在每个分区中的大和小行数。

MAX_ROWS选项对于创建具有额外分区的NDB Cluster表也很有用,因此可以更好地存储哈希索引。


此处列出了分区的一些优点:


  • 通过分区,可以在一个表中存储比在单个磁盘或文件系统分区上保存的数据更多的数据。
  • 通过删除仅包含该数据的分区(或多个分区),通常可以轻松地从分区表中删除失去其实用性的数据。 相反,在某些情况下,通过添加一个或多个新分区来特别存储该数据,可以极大地促进添加新数据的过程。
  • 由于满足给定WHERE子句的数据只能存储在一个或多个分区上,因此可以大大优化某些查询,这会自动从搜索中排除任何剩余的分区。 由于在创建分区表后可以更改分区,因此可以重新组织数据以增强在设置分区方案时可能不常使用的频繁查询。 这种排除不匹配分区(以及它们包含的任何行)的能力通常称为分区修剪。


此外,MySQL支持查询的显式分区选择。 例如,SELECT * FROM t PARTITION(p0,p1)WHERE c <5仅选择与WHERE条件匹配的分区p0和p1中的那些行。 在这种情况下,MySQL不检查表t的任何其他分区; 当您已经知道要检查哪个或哪些分区时,这可以大大加快查询速度。 数据修改语句DELETE,INSERT,REPLACE,UPDATE和LOAD DATA,LOAD XML也支持分区选择。 有关更多信息和示例,请参阅这些语句的说明。

分享好友

分享这个小栈给你的朋友们,一起进步吧。

MySQL干货资料
创建时间:2020-05-06 14:18:32
每天都有干货输出哦
展开
订阅须知

• 所有用户可根据关注领域订阅专区或所有专区

• 付费订阅:虚拟交易,一经交易不退款;若特殊情况,可3日内客服咨询

• 专区发布评论属默认订阅所评论专区(除付费小栈外)

技术专家

查看更多
  • 飘絮絮絮丶
    专家
戳我,来吐槽~