PolarDB-X的Hash类型分区可细分为Hash分区与Key分区两种类型。Hash分区与Key分区是原生MySQL的标准分区语法之一,PolarDB-X为提供灵活强大的分区管理能力(例如分裂、合并与迁移等)以及考虑支持向量分区键下热点散裂,PolarDB-X不仅在语法上尽量兼容了MySQL的Hash分区与Key分区的建表语法(PolarDB-X仅兼容了语法,分区路由的实现与MySQL并非一致),但是对于Key分区与Hash分区的路由行为重新进行了定义。Key分区与Hash分区使用区别如下表所示:
| 分区策略 | 分区键支持 | 是否支持分区函数 | 语法示例 | 特点与限制 | 路由描述(点查) |
|---|---|---|---|---|---|
| Key(默认的分区策略) | 单列分区键 | 否 | PARTITION BY KEY(c1) |
|
|
| 向量分区键 | 否 | PARTITION BY KEY(c1,c2,...,cn) |
|
| |
| Hash | 单列分区键 | 否 | PARTITION BY HASH(c1) |
| PARTITION BY HASH(c1)与PARTITION BY KEY(c1)完全等同 ,其路由算法与PARTITION BY KEY(c1)完全一致。 |
| 是 | PARTITION BY HASH(YEAR(c1)) |
| |||
| 向量分区键 | 否 | PARTITIONBY HASH(c1,c2,...,cn) |
|
|
示例1-1:Key分区
Key分区也是PolarDB-X的默认分区方式。 Key分区支持向量分区键。例如,用户想按用户名字name列与用户ID两个列作为分区键进行分区,预建分区数目可以指定为8,可以使用以下的语法建表:
CREATE TABLE key_tbl(
id bigint not null auto_increment,
bid int,
name varchar(30),
birthday datetime not null,
primary key(id)
)
PARTITION BY KEY(name, id)
PARTITIONS 8;根据KEY分区的特点,如上所示向量分区键的分区表,当它进行路由计算时,默认只使用向量分区键的第1个分区列(name)进行路由。因此,业务查询SQL的WHERE条件表达式中,只需要含有第1个分区列的等值条件,即可命中分区裁剪的优化,如下所示:
##(命中分区裁剪,只需扫描一个分区)
SELECT id from key_tbl where name='Jack';若第1个分区列name存在分布不均衡或者出现数据热点,您也可以通过分区分裂操作(详细请参考表组级分区变更语法(AUTO模式)),并使用下一个分区列(如id)进行分区分裂,从而解决数据不均衡的问题。
如果一个由N个分区列组成的向量分区键,若它实际路由使用到的分区列数目是前K个(1<=K<=N),则查询SQL的WHERE条件表达式只需要包含由这前K个分区列组成的前缀分区裂即可命中分区裁剪。
示例1-2:Hash分区
如果您想使用用户ID作为分区键进行水平分区,可以使用Hash分区进行建表,分区数目可以指定为8,建表语法示例如下:
CREATE TABLE hash_tbl(
id bigint not null auto_increment,
bid int,
name varchar(30),
birthday datetime not null,
primary key(id)
)
partition by hash(id)
partitions 8;Hash分区支持使用分区函数表达式(例如YEAR/TO_DAYS/...等)来将时间类型转换成整数类型。因此,如果您想按用户出生日期birthday列进行分区, 并且预建的Hash分区数目是8, 也可以使用如下语句建表:
CREATE TABLE hash_tbl_todays(
id bigint not null auto_increment,
bid int,
name varchar(30),
birthday datetime not null,
primary key(id)
)
PARTITION BY HASH(TO_DAYS(birthday))
PARTITIONS 8;目前PolarDB-X的分区函数仅支持以下的函数列表:
- YEAR
- MONTH
- DAYOFMONTH
- DAYOFWEEK
- DAYOFYEAR
- TO_DAYS
- TO_MONTHS
- TO_WEEKS
- TO_SECONDS
- UNIX_TIMESTAMP
- SUBSTR/SUBSTRING
因此,除SUBSTR/SUBSTRING的分区键类型必须为字符串类型以外,其余分区函数的分区键的类型必须是时间类型(DATE/DATETIME/TIMESTAMP),其它类型不支持使用分区函数。
示例1-3:Hash分区扩展
PolarDB-X对Hash分区的语法进行扩展,让Hash分区支持使用向量分区键 (原生MySQL的标准分区语法,可使用如下语句:
CREATE TABLE hash_tbl2(
id bigint not null auto_increment,
bid int,
name varchar(30),
birthday datetime not null,
primary key(id)
)
PARTITION BY HASH(name, birthday)
PARTITIONS 8;与Key分区不同, Hash分区使用向量分区键,这样的分区表在分区路由计算时,是所有分区列同时参与哈希值计算与路由计算,所以,它会要求查询SQL的WHERE条件表达式必须要含包所有的分区列的等值条件才能命中分区裁剪,如下示例的SQL1可以命中hash_tbl2的分区裁剪,而SQL2则不能命中hash_tbl2的分区裁剪:
##SQL1(命中分区裁剪,只扫描一个分区):
SELECT id from hash_tbl2 where name='Jack' and birthday='1990-11-11';
##SQL2(没命中分区裁剪,全分区扫描):
SELECT id from hash_tbl2 where name='Jack';Hash分区由于一开始就直接使用所有的分区键进行哈希值计算,所以理论上,它比使用向量分区键的Key分区会打散得更均衡,但它不再支持使用下一个列(因为已经没有列可用)进行热点散列。
相关限制
- 数据类型限制
- 整数类型: BIGINT/BIGINT UNSINGED/INT UNSINGED/INT/MEDIUMINT/MEDIUMINT UNSINGED/SMALLINT/SMALLINT UNSINGED/TINYINT/TINYINT UNSINGED;
- 时间类型:DATETIME/DATE/TIMESTAMP;
- 字符串类型:CHAR/VARCHAR。
- 语法限制
- Hash分区的单列分区键支持使用分区函数,且分区键类型必须为时间类型;
- Hash分区的向量分区键不允许使用分区函数,不支持热点分列;
- 默认最大分区数目不允许超过8192个;
- 默认最大分区列数目不允许超过5个。
数据均匀性
- Key分区与Hash分区内置的一致性Hash散列算法是经过业界广泛测试的、冲突概率低且性能良好的散列算法 MurmurHash3。
- 基于MurmurHash3的特性,一般情况下,当分区键不同取值的数目N大于3000时,Key分区与Hash分区的数据分布才会相对均衡,且N的值越大,数据分布也将越均衡。




