概述

分区类型介绍

PolarDB-X数据库提供了多种不同类型的分区策略,用于数据库控制如何将数据放入分区, 包括以下几种:

  • Hash类型的分区策略

    • HASH(兼容社区MySQL的HASH分区语法)

    • KEY(兼容社区MySQL的KEY分区语法)

  • Range类型的分区策略

    • RANGE(兼容社区MySQL的RANGE分区语法)

    • RANGE COLUMNS(兼容社区MySQL的RANGE COLUMNS分区语法)

  • List类型的分区策略

    • LIST(兼容社区MySQL的LIST分区语法)

    • LIST COLUMNS(兼容社区MySQL的LIST COLUMNS分区语法)

  • 特定场景的分区策略

    CO_HASH(PolardDB-X 的特色分区语法)

Hash类型

基于用户指定的分区列或分区函数表达式的值,使用内置的一致性哈希算法计算其哈希值并进行分区路由的策略。按是否支持使用分区函数表达式或使用多个分区列作为分区键,Hash分区策略又可以细分为Key分区Hash分区两种分区策略。

表 1. Key分区策略与Hash分区策略对比

分区策略

分区键支持

是否支持分区函数

语法示例

特点与限制

路由描述(点查)

Key(默认的分区策略)

单列分区键

PARTITION BY KEY(c1)

  • 不支持热点分裂;

  • 最多有1个分区列参与路由计算;

  1. 按c1列的值,使用一致性哈希算法计算其哈希c1_hash;

  2. 按哈希值 c1_hash进行分区路由。

向量分区键

PARTITION BY KEY(c1,c2,...,cn)

  • 支持热点分裂;

  • 建表后默认仅第1个分区列c1实际参与路由计算,热点分裂时可以使用c2,...,cn等更多的分区列;

  • 最多允许n个分区列同时参与路由计算;

  • 分区列数目n默认不能超过5个。

  1. (c1,c2,...,cn)这N个列的值组成一组分区键向量,并使用一致性哈希算法为向量的各个列的值计算其哈希值,从而将一个分区键向量映射成一个哈希值向量(c1_hash,c2_hash,...,cn_hash)

  2. 将哈希值向量(c1_hash,c2_hash,...,cn_hash)按range路由并找到目标分区。

Hash

单列分区键

PARTITION BY HASH(c1)

  • 不支持热点分裂;

  • 一个分区列参与路由。

  • 目前支持11个分区函数:

    • YEAR

    • MONTH

    • DAYOFMONTH

    • DAYOFWEEK

    • DAYOFYEAR

    • TO_DAYS

    • TO_MONTHS

    • TO_WEEKS

    • TO_SECONDS

    • UNIX_TIMESTAMP

    • SUBSTR/SUBSTRING

PARTITION BY HASH(c1)与PARTITION BY KEY(c1)完全等同 ,其路由算法与PARTITION BY KEY(c1)完全一致。

PARTITION BY HASH(YEAR(c1))

  1. 按c1列的值,使用YEAR分区函数计算其对应的年份year;

  2. 将年份year使用一致性哈希算法计算其哈希值year_hash;

  3. 按哈希值year_hash进行分区路由。

向量分区键

PARTITIONBY HASH(c1,c2,...,cn)

  • 不支持热点分裂;

  • 建表后,n个分区列将同时与路由;

  • 分区列数目n默认不能超过5个。

  1. (c1,c2,...,cn)这N个分区列的值组成一组向量,并使用一致性哈希算法,计算该向量对应哈希值hashVal;

  2. 按哈希hashVal进行分区路由。

Range类型

基于用户指定的分区列或分区函数表达式的值,通过比较计算来确定数据位于哪些预定义分区的范围并进行分区路由的策略。按是否支持使用分区函数表达式或使用多个分区列作为分区键,Range分区策略又可以细分为Range Columns分区Range分区两种分区策略。

表 2. Range Columns分区策略与Range分区策略对比

分区策略

分区键支持

是否支持分区函数

语法示例

特点与限制

路由描述(点查)

Range Columns

单列分区键& 向量分区键

PARTITION BY RANGE COLUMNS (c1,c2,...,cn) ( PARTITION p1 VALUES LESS THAN (1,10,...,1000), PARTITION p2 VALUES LESS THAN (2,20,...,2000) ...)

支持热点分裂(例如c1有热点值88,可以使用c2进行分区分裂解决热点)。

  1. (c1,c2,...,cn)这N个列的值组成一组分区键向量;

  2. 根据这个分区键向量(c1,c2,...,cn)按二分查找算法判断它属于哪个预定义分区,并最终路由到目标分区。

Range

单列分区键

PARTITION BY RANGE(YEAR(c1)) ( PARTITION p1 VALUES LESS THAN (2019), PARTITION p2 VALUES LESS THAN (2021) ...)

  • 不支持热点分裂;

  • 目前支持的分区函数:

    • YEAR

    • MONTH

    • DAYOFMONTH

    • DAYOFWEEK

    • DAYOFYEAR

    • TO_DAYS

    • TO_MONTHS

    • TO_WEEKS

    • TO_SECONDS

    • UNIX_TIMESTAMP

    • SUBSTR/SUBSTRING

  1. 按c1列的值,使用YEAR分区函数计算其对应的年份year;

  2. 年份year按二分查找算法判断它属于哪个预定义分区,并路由到目标分区。

List类型

与Range分区策略类似,基于用户指定的分区列或分区函数表达式的值,通过比较计算来确定数据位于哪些预定义分区的取值集合并进行分区路由的策略。按是否多个分区列作为分区键以及其使用方式的不同,List类型也分为List Columns分区List分区两种分区策略。

表 3. List Columns分区策略与List分区策略对比

分区策略

分区键支持

是否支持分区函数

语法示例

特点与限制

路由描述(点查)

List Columns

单列分区键& 向量分区键

PARTITION BY LIST COLUMNS (c1,c2,...,cn) ( PARTITION p1 VALUES IN ((1,10,...,1000),(2,20,...,2000) ), PARTITION p2 VALUES IN ((3,30,...,3000),(3,30,...,3000) ), ...)

不支持热点分裂

  1. (c1,c2,...,cn)这N个列的值组成一组分区键向量;

  2. 根据这个分区键向量(c1,c2,...,cn)按二分查找算法判断它属于哪个预定义分区,并最终路由到目标分区。

List

单列分区键

PARTITION BY LIST(YEAR(c1)) ( PARTITION p1 VALUES IN (2018,2019), PARTITION p2 VALUES IN (2020,2021) ...)

不支持热点分裂。

CoHash类型

PolarDB-X还针对比较常见的特定的应用场景新扩展了一种新的名为CoHash的哈希分区策略,该策略可有效解决一个表需要同时按多个不同的相互有协同关系的分区列进行水平分区的问题。

由于CoHash分区策略与前面的Hash/Key分区策略有些类似,以下是它们的一些主要用法异同的对比。

表 4. 与Hash/Key分区策略的主要区别

主要区别点

CO_HASH

KEY

Hash

语法示例

PARTITION BY

CO_HASH(c1, c2)

PARTITOINS 8

PARTITION BY

KEY(c1, c2)

PARTITOINS 8

PARTITION BY

HASH(c1, c2)

PARTITOINS 8

单列分区键

不支持

支持

支持

向量分区键

支持

支持。

支持

向量分区列是否允许使用分区函数

允许。例如PARTITION BY

CO_HASH(

/*取c1列的后4位字符*/

RIGHT(c1, 4),

/*取c2列的后4位字符*/

RIGHT(c2, 4)

)

PARTITOINS 8

不允许

不允许

分区列之间的关系

协同关系。同一个的分区列取值的协同关系由业务提供并负责维护。例如:

  • c1 与 c2 的取值总是相同

  • 适合使用 CO_HASH(c1, c2)

  • c1 与 c2 的后4位字符总是相同

  • 适合使用 CO_HASH(RIGHT(c1,4), RIGHT(c2,4)))

类似联合索引的前缀关系。

类似联合索引的前缀关系。

前缀列等值查询分区裁剪及示例

支持。例如:

  • c1='x': 支持分区裁剪并路由到单个分区;

  • c1='x' and c2='y': 支持分区裁剪并路由到一个或0个分区(如果 c1='x'与c2='y'的路由分区不一样,则返回0个分区)。

支持。例如:

  • c1='x':支持分区裁剪并路由到一个或多个分片(如果x值进行了热点分列,会返回多个分区);

  • c1='x' and c2='y':支持分区裁剪并路由到单个分区。

不支持,必须带上全分区列等值条件才支持分区裁剪。例如:

  • c1='x': 无法裁剪并全分区扫描;

  • c1='x' and c2='y': 支持分区裁剪并路由到单个分区。

非前缀列等查询分区裁剪及示例

支持。所有分区列的等值条件均支持独立的分区裁剪。例如:

  • c2='x': 支持分区裁剪并路由到单个分区;

  • c1='x' or c2='y': 支持分区裁剪并路由到1个或2个分区(如果 c1='x'与c2='y'的路由分区是一样,则返回1个分区,否则扫描2个分区)。

不支持。非前缀分区等值条件必须全分区扫描。例如:

  • c2='x': 全分区扫描;

  • c1='x' or c2='y': 全分区扫描。

不支持。非前缀分区等值条件必须全分区扫描。例如:

  • c2='x': 全分区扫描;

  • c1='x' or c2='y': 全分区扫描。

范围查询

不支持。全分区扫描。

不支持。全分区扫描。

不支持。全分区扫描。

路由描述(点查)

  1. 提取c1列(其他的分区列与之一样)的等值查询的原始值 v1 ;

  2. 如果c1列使用了分区函数,则计算v1列的分区函数取值,f1 = partFunc(v1),否则取 f1 = v1;

  3. 使用一致性哈希算法计算 f1 的哈希值 c1_hash(long类型的整数);

  4. 按哈希值c1_hash 进行分区路由。

可参考前边的“Key分区与Hash 分区”的描述,此处忽略。

可参考前边的“Key分区与 Hash分区”的描述,此处忽略。

热点分裂

不支持。无法对某个具体的热点值(比如c1='88') 进行进一步热点分裂

支持

不支持

分区管理(常见的分区分裂、合并与迁移等)

支持

支持

支持

二级分区

支持

支持

支持