19.2.2 LIST Partitioning
List partitioning 在MySQL 里类似于range 分区 在许多方面。
在RANGE 分区, 每个分区必须被明确定义。两种分区之间主要的差别是,
在list 分区,每个分区被定义,被选择基于一个列的值 在一组列表中的一个.而不是一组连续的范围。
这是通过使用 PARTITION BY LIST(表达式),当表达式的列值或者一个表达式基于一个列值
和返回一个整型值,然后定义每个分区通过value_list的一个值,value_list是一个逗号分隔的整数。
注意:
在MySQL 5.6中, 是可能的 于一个整数的列表相比(可能是NULL)
与范围定义的分区不同,列分区不需要任何特定的顺序声明。
对于后面的例子:
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
);
假设在下面的表格中,有20个视频商店分区在4个连锁店中:
Region Store ID Numbers
North 3, 5, 6, 9, 17
East 1, 2, 10, 11, 19, 20
West 4, 12, 13, 14, 18
Central 7, 8, 15, 16
在这样的方式下分区,将此表以相同的访问存储在相同的分区里,你可以使用下面的语句:
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 LIST(store_id) (
PARTITION pNorth VALUES IN (3,5,6,9,17),
PARTITION pEast VALUES IN (1,2,10,11,19,20),
PARTITION pWest VALUES IN (4,12,13,14,18),
PARTITION pCentral VALUES IN (7,8,15,16)
);
这使得它更加容易的增加和删除雇员记录与特定区域的,例如,
假设所用存储在West 区域被出售给了另外一家公司。在MySQL 5.6里,所有相关的记录可以被删除
使用ALTER TABLE employees TRUNCATE PARTITION pWest,相比删除语句 DELETE FROM employees WHERE store_id IN (4,12,13,14,18);
更有效率
(使用ALTER TABLE employees DROP PARTITION pWest would also delete all of these rows,会删除分区pWest 从表定义里,
你需要 ALTER TABLE … ADD PARTITION statement to restore the table’s original partitioning scheme)
与RANGE 分区相比, 没有 “catch-all”比如MAXVALUE; 所有的被期望的值应该被划分到 PARTITION … VALUES IN (…) clauses
mysql> CREATE TABLE h2 (
-> c1 INT,
-> c2 INT
-> )
-> PARTITION BY LIST(c1) (
-> PARTITION p0 VALUES IN (1, 4, 7),
-> PARTITION p1 VALUES IN (2, 5, 8)
-> );
Query OK, 0 rows affected (0.11 sec)
mysql> INSERT INTO h2 VALUES (3, 5);
ERROR 1525 (HY000): Table has no partition for value 3
当使用一个INSERT 语句插入多行时, 该行为取决于该表是否使用了事务存储引擎。对于InnoDB表.
一个语句被认为是一个单独的事务, 所以任何不匹配的值的存在都会导致语句完全失败,
没有记录被插入。
你可以使用IGNORE 关键字来忽略,如果这样做, 不匹配的记录不会被插入,但任何与匹配值的行插入,并且没有错误报告
mysql> TRUNCATE h2;
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM h2;
Empty set (0.00 sec)
mysql> INSERT IGNORE INTO h2 VALUES (2, 5), (6, 10), (7, 5), (3, 1), (1, 9);
Query OK, 3 rows affected (0.00 sec)
Records: 5 Duplicates: 2 Warnings: 0
mysql> SELECT * FROM h2;
+——+——+
| c1 | c2 |
+——+——+
| 7 | 5 |
| 1 | 9 |
| 2 | 5 |
+——+——+
3 rows in set (0.00 sec)