19.2 Partitioning Types
[+/-]
19.2.1 RANGE Partitioning
19.2.2 LIST Partitioning
19.2.3 COLUMNS Partitioning
19.2.4 HASH Partitioning
19.2.5 KEY Partitioning
19.2.6 Subpartitioning
19.2.7 How MySQL Partitioning Handles NULL
这个章节讨论分区的类型,包含下面的信息:
RANGE partitioning: 这种分区类型的记录 基于列值落入给定的范围。
LIST partitioning.: 类似于range 分区, 除了 分区被选择是基于列的匹配,基于一个离散值。
一个很常见的使用数据分区是将数据按日期分区。 一些数据库系统支持明确的数据分区,
在Mysql 5.6中没有实现。然而, 在Mysql 创建分区基于DATE,TIME,或者DATATIME列 并不麻烦
当分区按KEY或者LINEAR KEY,你可以使用DATE,TIME或者DATETIME 列作为分区列 ,
不需要执行对列值的任何修改。
CREATE TABLE members (
firstname VARCHAR(25) NOT NULL,
lastname VARCHAR(25) NOT NULL,
username VARCHAR(16) NOT NULL,
email VARCHAR(35),
joined DATE NOT NULL
)
PARTITION BY KEY(joined)
PARTITIONS 6;
在MySQL 5.6,它可能使用DATE或者DATETIME列作为分区列使用range 和list 分区
MySQL 的其他分区的类型,然而, 需要一个分区的表达式来产生一个整型或者NULL,
如果你期望使用date-based 分区通过RANGE,LIST,HASH或者LINEAR HASH,你可以简单的
使用一个函数来操作 DATE, TIME, or DATETIME column
CREATE TABLE members (
firstname VARCHAR(25) NOT NULL,
lastname VARCHAR(25) NOT NULL,
username VARCHAR(16) NOT NULL,
email VARCHAR(35),
joined DATE NOT NULL
)
PARTITION BY RANGE( YEAR(joined) ) (
PARTITION p0 VALUES LESS THAN (1960),
PARTITION p1 VALUES LESS THAN (1970),
PARTITION p2 VALUES LESS THAN (1980),
PARTITION p3 VALUES LESS THAN (1990),
PARTITION p4 VALUES LESS THAN MAXVALUE
);
在本章的下面章节里,可以找到使用日期进行分区的其他示例
重要的是记住,不管你使用的是什么分区类型,在创建时,都会自动编号,按顺序创建,
从0开始, 当一个新的记录插入到分区表,这些分区号被用于确认正确的分区。
比如,如果你的表有4个分区, 这些分区编号从0,1,2和3.
对于RANGE 和LIST 分区类型,必须确保每个每个分区定义一个分区号。对于HASH分区,
用户单数必须返回一个大于0的整数。
分区的名字通常遵循 MySQL 标示符的规则,比如表和数据库。然而,分区名字不区分大小写:
mysql> CREATE TABLE t2 (val INT)
-> PARTITION BY LIST(val)(
-> PARTITION mypart VALUES IN (1,3,5),
-> PARTITION MyPart VALUES IN (2,4,6)
-> );
ERROR 1488 (HY000): Duplicate partition name mypart
19.2.1 RANGE Partitioning
按range 分区是被分区以这种方式,每个分区包含记录是在一个给定的范围的分区上。
范围是连续的但是不能重叠, 并且被定义使用 VALUES LESS THAN 操作。对于接下来的几个例子,假设你正在创建一个表,
如下面的20个视频商店的连锁店的人事记录,编号1至20:
CREATE TABLE employees (
id INT NOT NULL,
fname VARCHAR(30),
lname VARCHAR(30),
hired DATE NOT NULL DEFAULT ‘1970-01-01’,
separated DATE NOT NULL DEFAULT ‘9999-12-31’,
job_code INT NOT NULL,
store_id INT NOT NULL
);
注意: employees 表在这里没有主键和唯一健。这个例子只是用于讨论目的,你应该记住表在实际中是极有可能有主键,唯一健
或者两者都有, 允许选择的分区列依赖 那些键使用的列,如果有的话 对于这些问题的讨论,请参见第19.6.1,分区键,主键和唯一键,”。
这个表可以用range分区 以几种方式,依赖你的需求。 一种方式是使用store_id 列
CREATE TABLE employees (
id INT NOT NULL,
fname VARCHAR(30),
lname VARCHAR(30),
hired DATE NOT NULL DEFAULT ‘1970-01-01’,
separated DATE NOT NULL DEFAULT ‘9999-12-31’,
job_code INT NOT NULL,
store_id INT NOT NULL
)
PARTITION BY RANGE (store_id) (
PARTITION p0 VALUES LESS THAN (6),
PARTITION p1 VALUES LESS THAN (11),
PARTITION p2 VALUES LESS THAN (16),
PARTITION p3 VALUES LESS THAN (21)
);
在这个分区方案里, 所有记录对应 employees 工作商店1-5 被存储在分区p0, 6-10的存储在p1,
注意每个分区按顺序定义, 从低到高。 这个需要PARTITION BY RANGE 语法,你可以把它看做是if ..elseif 语句
这是很容易的确定一条新的记录包含数据(72, ‘Michael’, ‘Widenius’, ‘1998-06-25’, NULL, 13)
被插入到分区p2, 当是当你增加21 商店呢? 根据这个规则, 没有规则覆盖这条记录,
它的store_id 是大于20. 那么一个错误导致,因为server 不知道数据存放到哪里。 你可以避免这个发生使用
“catchall” VALUES LESS THAN clause 在创建表的时候,提供大于最大的值的记录
CREATE TABLE employees (
id INT NOT NULL,
fname VARCHAR(30),
lname VARCHAR(30),
hired DATE NOT NULL DEFAULT ‘1970-01-01’,
separated DATE NOT NULL DEFAULT ‘9999-12-31’,
job_code INT NOT NULL,
store_id INT NOT NULL
)
PARTITION BY RANGE (store_id) (
PARTITION p0 VALUES LESS THAN (6),
PARTITION p1 VALUES LESS THAN (11),
PARTITION p2 VALUES LESS THAN (16),
PARTITION p3 VALUES LESS THAN MAXVALUE
);
注意:
另外一个方式来避免这个错误,当不匹配的值被找到使用IGNORE 关键字,作为INSERT语句的一部分
MAXVALUE 代表一个整数的值总是大于 最大可能的值(作为一个上界),现在,
任何行的store_id列值 是大于或者=16被存储到P3分区, 在未来的某一刻,当店面数量增加到了25,30
或者更多,你可以使用ALTER TABLE 语句来增加新的分区来存储21-25, 26-30, and so on
以同样的方式,你可以根据员工的 job code 来分区, 基于job_code 列来分区。
比如,假设2位job codes 用于普通的(在商店)的工人,三位数字代码用于办公室和支持人员,和四位数字代码用于管理位置,您可以使用以下语句创建分区表:
CREATE TABLE employees (
id INT NOT NULL,
fname VARCHAR(30),
lname VARCHAR(30),
hired DATE NOT NULL DEFAULT ‘1970-01-01’,
separated DATE NOT NULL DEFAULT ‘9999-12-31’,
job_code INT NOT NULL,
store_id INT NOT NULL
)
PARTITION BY RANGE (job_code) (
PARTITION p0 VALUES LESS THAN (100),
PARTITION p1 VALUES LESS THAN (1000),
PARTITION p2 VALUES LESS THAN (10000)
);
在这种情况下,所有的有关商店的工人将被存储在p0分区,P1与办公室和支持人员,和那些与分区P2经理。
相比拆分数据根据store number,你可以使用一个表达式基于一个DATE列代替。
比如, 让我们假设你希望分区基于 一年内 每个员工离开公司, YEAR的值(单独的),一个例子:
CREATE TABLE employees (
id INT NOT NULL,
fname VARCHAR(30),
lname VARCHAR(30),
hired DATE NOT NULL DEFAULT ‘1970-01-01’,
separated DATE NOT NULL DEFAULT ‘9999-12-31’,
job_code INT,
store_id INT
)
PARTITION BY RANGE ( YEAR(separated) ) (
PARTITION p0 VALUES LESS THAN (1991),
PARTITION p1 VALUES LESS THAN (1996),
PARTITION p2 VALUES LESS THAN (2001),
PARTITION p3 VALUES LESS THAN MAXVALUE
);
在这个章节, 所有1991年离开的员工 存储在P0分区,1991到1995 存储在P1,
在1996到2000 存储在P2
也可以通过RANGE 分区, 基于TIMESTAMP 列,使用UNIX_TIMESTAMP()函数:
CREATE TABLE quarterly_report_status (
report_id INT NOT NULL,
report_status VARCHAR(20) NOT NULL,
report_updated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)
PARTITION BY RANGE ( UNIX_TIMESTAMP(report_updated) ) (
PARTITION p0 VALUES LESS THAN ( UNIX_TIMESTAMP(‘2008-01-01 00:00:00’) ),
PARTITION p1 VALUES LESS THAN ( UNIX_TIMESTAMP(‘2008-04-01 00:00:00’) ),
PARTITION p2 VALUES LESS THAN ( UNIX_TIMESTAMP(‘2008-07-01 00:00:00’) ),
PARTITION p3 VALUES LESS THAN ( UNIX_TIMESTAMP(‘2008-10-01 00:00:00’) ),
PARTITION p4 VALUES LESS THAN ( UNIX_TIMESTAMP(‘2009-01-01 00:00:00’) ),
PARTITION p5 VALUES LESS THAN ( UNIX_TIMESTAMP(‘2009-04-01 00:00:00’) ),
PARTITION p6 VALUES LESS THAN ( UNIX_TIMESTAMP(‘2009-07-01 00:00:00’) ),
PARTITION p7 VALUES LESS THAN ( UNIX_TIMESTAMP(‘2009-10-01 00:00:00’) ),
PARTITION p8 VALUES LESS THAN ( UNIX_TIMESTAMP(‘2010-01-01 00:00:00’) ),
PARTITION p9 VALUES LESS THAN (MAXVALUE)
);
任何其他表达式调用TIMESTAMP 值是不允许的
你想要删除旧的数据,如果你使用分区方案开显示以前的雇员表,你可以简单的使用ALTER TABLE employees DROP PARTITION p0;
来删除所有1991年的离职的员工 。
你想使用一列包含date或者time值,或者包含其他产生的值。
你经常会运行m直接抵赖分区表的列,例如,当执行一个查询,如
SELECT COUNT(*) FROM employees WHERE separated BETWEEN ‘2000-01-01’ AND ‘2000-12-31’ GROUP BY store_id;,
MySQL 会快速的确定只有分区P2需要被扫描, 因为剩下的分区不包含任何满足的数据。
一个变种基于分区是RANGE COLUMNS 分区, 分区通过RANGE 列 使它采用多个列来定义分区range ,适用于
放置在分区中的记录和确定包含或者排除特定的分区当执行分区裁剪
基于时间江恩的分区方案,如果你想实现一个分区方案基于MySQL的5.6时间范围或时间,你有两个选择:
1 范围分区的分区表, 对于分区表达式,适用一个函数操作DATE,TIME或者DATETIME 列,返回一个整型:
CREATE TABLE members (
firstname VARCHAR(25) NOT NULL,
lastname VARCHAR(25) NOT NULL,
username VARCHAR(16) NOT NULL,
email VARCHAR(35),
joined DATE NOT NULL
)
PARTITION BY RANGE( YEAR(joined) ) (
PARTITION p0 VALUES LESS THAN (1960),
PARTITION p1 VALUES LESS THAN (1970),
PARTITION p2 VALUES LESS THAN (1980),
PARTITION p3 VALUES LESS THAN (1990),
PARTITION p4 VALUES LESS THAN MAXVALUE
);
在MySQL 5.6,它也可能是基于TIMESTAMP 列的分区,适用UNIX_TIMESTAMP() function, as shown in this example:
CREATE TABLE quarterly_report_status (
report_id INT NOT NULL,
report_status VARCHAR(20) NOT NULL,
report_updated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)
PARTITION BY RANGE ( UNIX_TIMESTAMP(report_updated) ) (
PARTITION p0 VALUES LESS THAN ( UNIX_TIMESTAMP(‘2008-01-01 00:00:00’) ),
PARTITION p1 VALUES LESS THAN ( UNIX_TIMESTAMP(‘2008-04-01 00:00:00’) ),
PARTITION p2 VALUES LESS THAN ( UNIX_TIMESTAMP(‘2008-07-01 00:00:00’) ),
PARTITION p3 VALUES LESS THAN ( UNIX_TIMESTAMP(‘2008-10-01 00:00:00’) ),
PARTITION p4 VALUES LESS THAN ( UNIX_TIMESTAMP(‘2009-01-01 00:00:00’) ),
PARTITION p5 VALUES LESS THAN ( UNIX_TIMESTAMP(‘2009-04-01 00:00:00’) ),
PARTITION p6 VALUES LESS THAN ( UNIX_TIMESTAMP(‘2009-07-01 00:00:00’) ),
PARTITION p7 VALUES LESS THAN ( UNIX_TIMESTAMP(‘2009-10-01 00:00:00’) ),
PARTITION p8 VALUES LESS THAN ( UNIX_TIMESTAMP(‘2010-01-01 00:00:00’) ),
PARTITION p9 VALUES LESS THAN (MAXVALUE)
);
在MySQL 5.6, 任何其他的表达式调用TIMESTAMP 是不允许的
注意:
在MySQL 5.6中使用UNIX_TIMESTAMP(timestamp_column) 作为分区表达式,用于LIST 分区,然而,这样做通常是不实际的
通过range 列的分区表, 使用DATE或者DATETIME 列作为分区列,
CREATE TABLE members (
firstname VARCHAR(25) NOT NULL,
lastname VARCHAR(25) NOT NULL,
username VARCHAR(16) NOT NULL,
email VARCHAR(35),
joined DATE NOT NULL
)
PARTITION BY RANGE COLUMNS(joined) (
PARTITION p0 VALUES LESS THAN (‘1960-01-01’),
PARTITION p1 VALUES LESS THAN (‘1970-01-01’),
PARTITION p2 VALUES LESS THAN (‘1980-01-01’),
PARTITION p3 VALUES LESS THAN (‘1990-01-01’),
PARTITION p4 VALUES LESS THAN MAXVALUE
)