您可以组合 HASH 和 RANGE 分区来创建更复杂的分区模式。您可以指定零个或多个 HASH 定义,后跟零个或一个 RANGE 定义。
每个定义可以包含一个或多个列。虽然枚举每个可能的分发模式都超出了本文档的范围,但是几个例子说明了一些可能性。
PARTITION BY HASH and RANGE
考虑上面的 简单哈希 示例,如果您经常查询一系列 sku 值,可以通过将哈希分区与范围分区相结合来优化示例。
以下示例仍然创建了16个 tablets ,首先将 id 列分为 4 个存储区,然后根据 sku 字符串的值应用范围划分将每个存储区分为四个数据块。至少四片(最多可达16张)。当您查询相邻范围的 sku 值时,您很有可能只需从四分之一的 tablets 中读取即可完成查询。
注意:
默认情况下,使用 PARTITION BY HASH 时,整个主键是散列的。要只对部分的主键进行散列,可以使用像 PARTITION BY HASH(id, sku) 这样的语法来指定它。
CREATE TABLE cust_behavior (
id BIGINT,
sku STRING,
salary STRING,
edu_level INT,
usergender STRING,
`group` STRING,
city STRING,
postcode STRING,
last_purchase_price FLOAT,
last_purchase_date BIGINT,
category STRING,
rating INT,
fulfilled_date BIGINT,
PRIMARY KEY (id, sku)
)
PARTITION BY HASH (id) PARTITIONS 4,
RANGE (sku)
(
PARTITION VALUES < 'g',
PARTITION 'g' <= VALUES < 'o',
PARTITION 'o' <= VALUES < 'u',
PARTITION 'u' <= VALUES
)
STORED AS KUDU;
该示例创建16个分区。您也可以使用 HASH(id,sku) PARTITIONS 16.但是,对于 sku 值的扫描几乎总是会影响所有16个分区,而不是可能限制为 4 。
Non-Covering Range Partitions ( 不覆盖分区 )
Kudu 1.0 及更高版本支持使用非覆盖范围分区,其解决方案如下:
-
没有未覆盖的范围分区,在需要考虑不断增加的主键的时间序列数据或其他模式的情况下,服务于旧数据的 tablet 的大小相对固定,而接收新数据的 tablets 将不受限制地增长。
-
在您希望根据其类别(如销售区域或产品类型)对数据进行分区的情况下,无需覆盖范围分区,则必须提前了解所有分区,或者如果需要添加或删除分区,请手动重新创建表。 例如引入或消除产品类型。
非覆盖范围分区有一些注意事项。请务必阅读链接:/docs/schema_design.html [Schema Design guide]。
此示例每年创建一个 tablet (共5个 tablets ),用于存储日志数据。该表仅接受 2012 年至 2016年 的数据。这些范围之外的键将被拒绝。
CREATE TABLE sales_by_year (
year INT, sale_id INT, amount INT,
PRIMARY KEY (sale_id, year)
)
PARTITION BY RANGE (year) (
PARTITION VALUE = 2012,
PARTITION VALUE = 2013,
PARTITION VALUE = 2014,
PARTITION VALUE = 2015,
PARTITION VALUE = 2016
)
STORED AS KUDU;
此示例每年创建一个 tablet (共5个 tablets ),用于存储日志数据。该表仅接受 2012 年至 2016年 的数据。这些范围之外的键将被拒绝。
当记录开始进入 2017 年时,他们将被拒绝。在这一点上, 2017 年的范围应该如下:
添加分区语句:
ALTER TABLE sales_by_year ADD RANGE PARTITION VALUE = 2017;
在需要数据保留的滚动窗口的情况下,范围分区也可能会丢弃。例如,如果不再保留 2012 年的数据,则可能会批量删除数据:
ALTER TABLE sales_by_year DROP RANGE PARTITION VALUE = 2012;
请注意,就像删除表一样,这不可逆转地删除存储在丢弃的分区中的所有数据。
Partitioning Rules of Thumb ( 拇指分区规则 )
-
对于大型表格,如事实表,目标是在集群中拥有核心数量的 tablets 。
-
对于小型表格(如维度表),目标是足够数量的 tablets ,每个 tablets 的大小至少为 1 GB 。
一般来说,请注意,在当前的实现中, tablets 的数量限制了读取的并行性。增加 tablets 数量超过核心数量可能会有减少的回报。