CREATE TABLE employees (
id INT NOT NULL,
first_name VARCHAR(30),
last_name VARCHAR(30),
store_id INT NOT NULL,
create_time DATE NOT NULL DEFAULT '9999-12-31',
)
partition BY
range(to_days(create_time))
(PARTITION p201701 VALUES LESS THAN (TO_DAYS('2017-02-01')) ENGINE = InnoDB,
PARTITION p201702 VALUES LESS THAN (TO_DAYS('2017-03-01')) ENGINE = InnoDB,
PARTITION p201703 VALUES LESS THAN (TO_DAYS('2017-04-01')) ENGINE = InnoDB,
PARTITION p2018 VALUES LESS THAN MAXVALUE ENGINE = InnoDB );
按照这种方式进行分区,那么如果创建日期在2017年2月1号之前的数据会放在p201701的这个分区;如果创建日期在2017年3月1号之前的数据会放在p201702的这个分区;如果创建日期在2017年4月1号之前的数据会放在p201703的这个分区;如果创建日期都不在前面的几个区间,那么会放在p2018的这个分区。
CREATE TABLE employees (
id INT NOT NULL,
first_name VARCHAR(30),
last_name VARCHAR(30),
store_id INT NOT NULL,
create_time DATE NOT NULL DEFAULT '9999-12-31',
)
PARTITION BY LIST(store_id)
PARTITION pNorth VALUES IN (1,5,6,9,17),
PARTITION pEast VALUES IN (2,4,10,11,19,20),
PARTITION pWest VALUES IN (3,12,13,14,18),
PARTITION pCentral VALUES IN (7,8,15,16)
);
store_id在1,5,6,9,17这些值中时候会被分配到pNorth这个分区中,其他的也一样。
注意:如果插入一行值时,里面的store_id不在上面的这列value_list时会出现插入失败并报错。而且。List分区没有range分区那样,range分区的“VALUES LESS THAN MAXVALUE”会将其他的值包含在内的定义。
CREATE TABLE employees (
id INT NOT NULL,
first_name VARCHAR(30),
last_name VARCHAR(30),
store_id INT NOT NULL,
create_time DATE NOT NULL DEFAULT '9999-12-31',
)
PARTITION BY HASH(id)
PARTITIONS 5;
线性hash分区:
CREATE TABLE employees (
id INT NOT NULL,
first_name VARCHAR(30),
last_name VARCHAR(30),
store_id INT NOT NULL,
create_time DATE NOT NULL DEFAULT '9999-12-31',
)
PARTITION BY LINEAR HASH(id)
PARTITIONS 5;
线性hash的计算方式:
假设一个表达式expr, 当使用线性哈希功能时,记录将要保存到的分区是num 个分区中的分区N,其中N是根据下面的算法得到:
1.找到下一个大于num的2的幂,我们把这个值称为V ,它可以通过下面的公式得到:
2. V = POWER(2, CEILING(LOG(2, num)))(例如,假定num是13。那么LOG(2,13)就是3.7004397181411。 CEILING(3.7004397181411)就是4,则V = POWER(2,4), 即等于16)。
3. 设置 N = F(column_list) & (V - 1).
4. 当 N >= num:
设置 V = CEIL(V / 2)
设置 N = N & (V - 1)
例如,假设表t1,使用线性哈希分区且有4个分区,是通过下面的语句创建的:
CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATE)
PARTITION BY LINEAR HASH( YEAR(col3) )
PARTITIONS 6;
现在假设要插入两行记录到表t1中,其中一条记录col3列值为’2003-04-14’,另一条记录col3列值为’1998-10-19’。第一条记录将要保存到的分区确定如下:
V = POWER(2, CEILING(LOG(2,7))) = 8
N = YEAR(‘2003-04-14’) & (8 - 1)
= 2003 & 7
= 3
(3 >= 6 为假(FALSE): 记录将被保存到#3号分区中)
第二条记录将要保存到的分区序号计算如下:
V = 8
N = YEAR(‘1998-10-19’) & (8-1)
= 1998 & 7
= 6
(6 >= 4 为真(TRUE): 还需要附加的步骤)
N = 6 & CEILING(5 / 2)
= 6 & 3
= 2
(2 >= 4 为假(FALSE): 记录将被保存到#2分区中)
按照线性哈希分区的优点在于增加、删除、合并和拆分分区将变得更加快捷,有利于处理含有极其大量(1000吉)数据的表。它的缺点在于,与使用常规HASH分区得到的数据分布相比,各个分区间数据的分布不大可能均衡。
在KEY分区中使用关键字LINEAR和在HASH分区中使用具有同样的作用,分区的编号是通过2的幂(powers-of-two)算法得到,而不是通过模数算法。
CREATE TABLE employees (
id INT NOT NULL,
first_name VARCHAR(30),
last_name VARCHAR(30),
store_id INT NOT NULL,
email VARCHAR(30) NOT NULL,
create_time DATE NOT NULL DEFAULT '9999-12-31',
)
PARTITION BY LINEAR Key(email)
PARTITIONS 5;
CREATE TABLE employees (
id INT NOT NULL,
first_name VARCHAR(30),
last_name VARCHAR(30),
store_id INT NOT NULL,
create_time DATE NOT NULL DEFAULT '9999-12-31',
)
partition BY
range(to_days(create_time))
(PARTITION p201701 VALUES LESS THAN (TO_DAYS('2017-02-01')) ENGINE = InnoDB,
PARTITION p201702 VALUES LESS THAN (TO_DAYS('2017-03-01')) ENGINE = InnoDB,
PARTITION p201703 VALUES LESS THAN (TO_DAYS('2017-04-01')) ENGINE = InnoDB);
alter table employees partition by range(to_days(create_time))
(PARTITION p201701 VALUES LESS THAN (TO_DAYS('2017-02-01')) ENGINE = InnoDB,
PARTITION p201702 VALUES LESS THAN (TO_DAYS('2017-03-01')) ENGINE = InnoDB,
PARTITION p201703 VALUES LESS THAN (TO_DAYS('2017-04-01')) ENGINE = InnoDB);
alter table employees add partition(PARTITION p2018 VALUES LESS THAN MAXVALUE);
alter table employees drop partition p201702;
ALTER TABLE employees REORGANIZE PARTITION p201701,p201702,p201703,p2018 INTO (PARTITION p0 VALUES LESS THAN MAXVALUE);
注意:
优点:
限制:
分区策略基于两个非常重要的假设:查询都能够过滤掉很多额外的分区,分区本身不会带来很多的额外的代价。在分区会在以下的场景中会有问题。
5,维护分区的成本可能很高。新增或者删除分区时,可能会很快。但是重组分区或者类似ALTER语句的操作:这类操作需要复制数据。重组分区的原理与ALTER类似,先创建一个临时的分区,然后将数据复制到其中,最后删除原分区。
如上所述:分区表不是什么“银弹”。下面是目前分区中一些其他的限制:
1,所有分区都必须使用相同的存储引擎。