tidb-in-action

6.4.1 TiDB 分区表简介

TiDB 是从 2.1 版本开始支持分区表,3.0 版本开始成熟使用,最新的 4.0 版本做了一些 Bug 修复和分区裁剪方面的增强和优化。

6.4.1.1 分区类型

当前支持的类型包括 Range 分区和 Hash 分区,不支持 MySQL 的 List 分区和 Key 分区。

Range 分区是指将数据行按分区表达式计算的值都落在给定的范围内。在 Range 分区中,你必须为每个分区指定值的范围,并且不能有重叠,通过使用 VALUES LESS THAN 操作进行定义。目前只支持单列的 Range 分区表。

Hash 分区主要用于保证数据均匀地分散到一定数量的分区里面。在 Hash 分区中,你只需要指定分区的数量。使用 Hash 分区时,需要在 CREATE TABLE 后面添加 PARTITION BY HASH (expr) PARTITIONS num ,其中:expr 是一个返回整数的表达式,它可以是一个列名,但这一列的类型必须整数类型;num 是一个正整数,表示将表划分为多少个分区。

6.4.1.2 约束和限制

1. 建表限制

建立主键和唯一键时必须包含分区表达式中用到的所有列,以 Range 分区举例说明:

CREATE TABLE employees_attendance  (
    id INT NOT NULL AUTO_INCREMENT,
    uid INT NOT NULL,
    name VARCHAR(25) NOT NULL,
    login_date date NOT NULL,
    create_time timestamp NOT NULL COMMENT '打卡时间',
    type tinyint NOT NULL DEFAULT '0' COMMENT '0:上班,1:下班',
    PRIMARY KEY (`id`,`login_date`),
    UNIQUE KEY `idx_attendance` (`uid`,`login_date`,`type`)
)
PARTITION BY RANGE COLUMNS(login_date)  (
    PARTITION p20200306 VALUES LESS THAN ('20200307'),
    PARTITION p20200307 VALUES LESS THAN ('20200308'),
    PARTITION pmax VALUES LESS THAN MAXVALUE
);

上表中主键和唯一键中都包括了分区 login_date 字段,否则就会报如下错误:

> ERROR 1503 (HY000): A (PRIMARY KEY/UNIQUE INDEX) must include all columns in the table's partitioning function

2. 分区管理和使用方面的限制

只要底层实现可能会涉及数据挪动的操作,TiDB 目前都不支持。包括且不限于:调整 Hash 分区表的分区数量;修改 Range 分区表的范围;合并分区;交换分区等。

使用方面的限制主要指 Load Data 不支持指定分区 load,例如:

load local data infile "xxx" into t partition (p1);

6.4.1.3 TiDB 4.0 对分区表的优化

TiDB 4.0 版本对分区表进行了较多的 Bug 修复、功能增强和性能提升,主要有以下几个方面: