查看系统是否支持分区表
MariaDB [(none)]> SHOW PLUGINS;
......
| unix_socket | ACTIVE | AUTHENTICATION | NULL | GPL |
| FEEDBACK | DISABLED | INFORMATION SCHEMA | NULL | GPL |
| user_variables | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| partition | ACTIVE | STORAGE ENGINE | NULL | GPL |
+-------------------------------+----------+--------------------+---------+---------+
54 rows in set (0.002 sec)
分区表要确定用于分区的a partitioning type类型和表达式a partitioning expression.分区类型确定分区表的行如何跨分区分布。某些分区类型要求用户指定一个分区表达式,该表达式确定将行存储在哪个分区中。各个分区的大小取决于分区类型。读写性能受分区表达式的影响。因此,应谨慎选择这些选择。
mariadb支持的type: RANGE LIST RANGE COLUMNS and LIST COLUMNS, HASH COLUMNS HASH KEY LINEAR HASH, LINEAR KEY SYSTEM_TIME
RANGE分区类型用于为每个分区分配由分区表达式生成的值的范围。范围必须是有序的,连续的且不重叠的。最小值始终包含在第一个范围内。最高值可以或可以不包括在最后一个范围内。
这种分区方法的一种变体RANGE COLUMNS允许我们使用多列和更多数据类型。
RANGE PARTITION BY RANGE(partitioning_expression)
(
PARTITION partition_name VALUES LESS THAN(value),
[PARTITION partition_name VALUES LESS THAN(value),...]
)
exampe:
#按年创建分区表
CREATE TABLE log
(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
timestamp DATETIME NOT NULL,
user INT UNSIGNED,
ip BINARY(16) NOT NULL,
action VARCHAR(20) NOT NULL,
PRIMARY KEY (id, timestamp)
)
ENGINE = InnoDB
PARTITION BY RANGE (YEAR(timestamp))
(
PARTITION p0 VALUES LESS THAN (2013),
PARTITION p1 VALUES LESS THAN (2014),
PARTITION p2 VALUES LESS THAN (2015),
PARTITION p3 VALUES LESS THAN (2016)
);
#按年和月创建
CREATE TABLE log
(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
timestamp TIMESTAMP NOT NULL,
user INT UNSIGNED,
ip BINARY(16) NOT NULL,
action VARCHAR(20) NOT NULL,
PRIMARY KEY (id, timestamp)
)
ENGINE = InnoDB
PARTITION BY RANGE (UNIX_TIMESTAMP(timestamp))
(
PARTITION p0 VALUES LESS THAN (UNIX_TIMESTAMP('2014-08-01 00:00:00')),
PARTITION p1 VALUES LESS THAN (UNIX_TIMESTAMP('2014-11-01 00:00:00')),
PARTITION p2 VALUES LESS THAN (UNIX_TIMESTAMP('2015-01-01 00:00:00')),
PARTITION p3 VALUES LESS THAN (UNIX_TIMESTAMP('2015-02-01 00:00:00'))
);
删除分区: ALTER TABLE log DROP PARTITION p0;
如果插入数据timestamp不在分区表范围会报错,通过IGNORE忽略错误
INSERT IGNORE INTO log(id,timestamp) VALUES
(1, '2016-01-01 01:01:01'),
(2, '2015-01-01 01:01:01');
SELECT * FROM log;
+----+---------------------+------+------------------+--------+
| id | timestamp | user | ip | action |
+----+---------------------+------+------------------+--------+
| 2 | 2015-01-01 01:01:01 | NULL | | |
+----+---------------------+------+------------------+--------+
通过MAXVALUE可以定义一个超出范围的最大值分区
CREATE TABLE log
(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
timestamp DATETIME NOT NULL,
user INT UNSIGNED,
ip BINARY(16) NOT NULL,
action VARCHAR(20) NOT NULL,
PRIMARY KEY (id, timestamp)
)
ENGINE = InnoDB
PARTITION BY RANGE (YEAR(timestamp))
(
PARTITION p0 VALUES LESS THAN (2013),
PARTITION p1 VALUES LESS THAN (2014),
PARTITION p2 VALUES LESS THAN (2015),
PARTITION p3 VALUES LESS THAN (2016),
PARTITION p4 VALUES LESS THAN MAXVALUE
);
LIST分区在概念上类似于RANGE分区。在这两种情况下,您都需要确定一个分区表达式(一个列,或者稍微复杂一点的计算),然后使用它来确定哪些分区将包含每一行。但是,对于RANGE类型,分区是通过为每个分区分配一个值范围来完成的。对于LIST类型,我们为每个分区分配一组值。如果分区表达式可以返回一组有限的值,则通常是首选方法。
这种分区方法的一种变体LIST COLUMNS允许我们使用多列和更多数据类型。
PARTITION BY LIST (partitioning_expression)
(
PARTITION partition_name VALUES IN (value_list),
[ PARTITION partition_name VALUES IN (value_list), ... ]
[ PARTITION partition_name DEFAULT ]
)
RANGE COLUMNS和LIST COLUMNS分别是RANGE和LIST的变体。对于这些分区类型,没有一个分区表达式。而是接受一个或多个列的列表。适用以下规则:
仅允许使用裸列;没有分区表达式
创建分区表语法
#创建RANGE COLUMNS PARTITION
PARTITION BY RANGE COLUMNS (col1, col2, ...)
(
PARTITION partition_name VALUES LESS THAN (value1, value2, ...),
[ PARTITION partition_name VALUES LESS THAN (value1, value2, ...), ... ]
)
#创建LIST COLUMNS PARTITION
PARTITION BY LIST COLUMNS (partitioning_expression)
(
PARTITION partition_name VALUES IN (value1, value2, ...),
[ PARTITION partition_name VALUES IN (value1, value2, ...), ... ]
[ PARTITION partititon_name DEFAULT ]
)