Chapter 19 Partitioning
Table of Contents [+/-]
19.1 Overview of Partitioning in MySQL
19.2 Partitioning Types [+/-]
19.3 Partition Management [+/-]
19.4 Partition Pruning
19.5 Partition Selection
19.6 Restrictions and Limitations on Partitioning [+/-]
这章讨论 MySQL 的用户自定义分区的实现。你可以判断你的MySQL Server 是否支持分区通过查看show PLUGINS;
注意:
先前的Mysql 版本有have_partitioning 参数, 在5.6.1被废弃
mysql> SHOW PLUGINS;
+------------+----------+----------------+---------+---------+
| Name | Status | Type | Library | License |
+------------+----------+----------------+---------+---------+
| binlog | ACTIVE | STORAGE ENGINE | NULL | GPL |
| partition | ACTIVE | STORAGE ENGINE | NULL | GPL |
| ARCHIVE | ACTIVE | STORAGE ENGINE | NULL | GPL |
| BLACKHOLE | ACTIVE | STORAGE ENGINE | NULL | GPL |
| CSV | ACTIVE | STORAGE ENGINE | NULL | GPL |
| FEDERATED | DISABLED | STORAGE ENGINE | NULL | GPL |
| MEMORY | ACTIVE | STORAGE ENGINE | NULL | GPL |
| InnoDB | ACTIVE | STORAGE ENGINE | NULL | GPL |
| MRG_MYISAM | ACTIVE | STORAGE ENGINE | NULL | GPL |
| MyISAM | ACTIVE | STORAGE ENGINE | NULL | GPL |
| ndbcluster | DISABLED | STORAGE ENGINE | NULL | GPL |
+------------+----------+----------------+---------+---------+
在任何情况下, 如果你没有看到partition plugin 列出的ACTIVE的值 在你的输出,那么你的版本不支持分区
MySQL 5.6 社区 binaries 提供了分区支持。
启用分区 如果你是从源代码编译的MySQL 5.6, 必须带 -DWITH_PARTITION_STORAGE_ENGINE option
如果你的Mysql binary 是支持分区的,什么都不需要做
如果你需要关闭分区功能,你可以启动 MySQL Server 带上 --skip-partition 选项,
导致have_partitioning 值为DISABLED. 当分区支持被关闭,你可以看到任何存在的分区表,drop 它们(尽管不建议这么做),
但是你不能操作它们或者访问它们的数据
19.1 Overview of Partitioning in MySQL Mysql 分区表概述
本节提供了在MySQL 5.6分区的概念性概述。
关于分区的约束和功能限制
SQL标准不提供太多的标准在数据物理存储方面, SQL语句 本身是单独工作的对于任何的数据结构或者media下的
schemas,tables,rows 或者列。然而, 最先进的数据库管理系统已经发展一些手段用于确定物理的位置
用于存储页顶的数据,硬件。在Mysql中,InnoDB 存储引擎一致支持表空间,
甚至引入分区,可以配置来利用不同的物理目录用于存储不同的数据库。
分区使这个概念进一步,可以让你分散单个表的一部分 到文件各种 按照规则 ,
不同的表的部分 被存储在单个表在不同的位置,用户选择规则通过分散数据通过分区函数实现,
它可以让Mysql 模块化, 简单的匹配一个范围的集合或者列表,一个内部的hash函数,
或者一个线性的hash 函数 ,函数是根据分区的类型进行选择.
在RANGE,LIST 和 HASH 分区, 分区列的值被传递给分区函数, 该函数返回一个整型值来表达分区的数据,
特定的记录存储在特定的分区。 这个函数是恒定的,非随机的。 它可能不包含任何查询,
但是 可能使用一个SQL表达式,-MAXVALUE <= intval <= MAXVALUE
(MAXVALUE 是用于表达上界)
对于[LINEAR]KEY,RANGE 列, LIST 列 分区,分区表达式有一列或者多列组成。
对于For[LINEAR] key 分区,Mysql支持分区函数。
这是已知的水平分区--,表的不同的记录可能分配到不同的物理分区。MySQL 5.6 不支持垂直分区,
表的不同的列被分配到不同的物理分区。
确定 Mysql Server binary 是否支持自定义分区。
创建分区表, 你可以使用大多数存储引擎。 MySQL 分区引擎运行在一个单独的层,可以去那些交互。
在MySQL 5.6中,所有的分区表的分区必须使用相同的存储引擎,比如:
你不能用MyISAM 用于一个分区,InnoDB 用于另一个分区。然而,但是不阻止你用不同的引擎用于不同的分区表
MySQL 分区不能用于MERGE,CSV,或者FEDERATED storage engines
通过KEY 或者LINEAR KEY 的分区是可能的with NDB 引擎, 但是其他类型的分区是不支持的在使用这种引擎的时候。
此外, 一个NDB引擎的表 使用用户定义的分区 必须有一个明确的主键, 表的分区表达式相关的列必须是主键的一部分。
然而, 如果没有列在PARTITION BY KEY 或者PARTITION BY LINEAR KEY 字句 在CREATE TABLE 或者ALTER TABLE 语句用于
创建或者修改一个用户定义的NDB引擎的表,那么表不需要一个明确的主键。
使用某个特定的存储引擎用于分区表,通常只需要使用[STORAGE] 引擎选项。
然而,你应该记住 [STORAGE] ENGINE(和其他的表的选项) 需要被列出在你CREATE TABLE 语句之前。
这里有个例子显示创建一个HASH 分区表有6个分区使用InnoDB存储引擎:
mysql> CREATE TABLE ti (id INT, amount DECIMAL(7,2), tr_date DATE)
-> ENGINE=INNODB
-> PARTITION BY HASH( MONTH(tr_date) )
-> PARTITIONS 6;
Query OK, 0 rows affected (0.30 sec)
mysql> desc ti;
+---------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| amount | decimal(7,2) | YES | | NULL | |
| tr_date | date | YES | | NULL | |
+---------+--------------+------+-----+---------+-------+
3 rows in set (0.03 sec)
每个分区选项 包括一个[STORAGE] ENGINE option, 但是在MySQL 5.6 这个没有影响
注意:
分区使用与所有的数据和索引,你不能只对数据进行分区而不分区索引,反之亦然.
每个分区的数据和索引可以分配到一个特定的目录 使用DATA DIRECTORY 和INDEX DIRECTORY 选项
用于PARTITION 字句 在CREATE TABLE 语句用于创建分区表的时候。
DATA DIRECTORY 和INDEX DIECTORY 对于一个单独的分区或者子分区 在MyISM 表(在WINDOWS上)是不支持的,
它们 支持单独的分区表和子分区表 在InnoDB 表(所有的平台)
表的分区表达式使用的所有的列 必须是每个唯一索引的一部分 ,包括任何的主键。
这意味着 有这样一个表,有下面的语句创建,不能被分区:
CREATE TABLE tnp (
id INT NOT NULL AUTO_INCREMENT,
ref BIGINT NOT NULL,
name VARCHAR(255),
PRIMARY KEY pk (id),
UNIQUE KEY uk (name)
);
因为 keys pl 和 uk 没有共同的列,没有可用的用于分区表达式的列。在这种情况下,
解决的办法是把name列 加到主键 ,或者把ID列 加到unique key .
此外, MAX_ROWS and MIN_ROWS 可以用来确定最大行和最小行,
分别的, 它们可以存储在每个分区。 MAX_ROWS选项是有用的 可以使MYSQL cluster 表和子分区表
被创建 with 额外的分区, 从而循序存储更大的hash indexes.