向 Timescale 超表添加额外的分区维度。您只能在空的超表上执行此 add_dimension 命令。要将普通表转换为超表,请调用 create_hypertable

您选择作为维度的列可以使用以下任一方式:

这些说明适用于自托管的 TimescaleDB 部署

最佳实践是不使用额外的维度。但是,Timescale Cloud 透明地提供无缝的存储扩展,包括存储容量和可用的存储 IOPS/带宽。

试用 Timescale Cloud

此页面描述了 TimescaleDB v2.13.0 中引入的通用超表 API。有关已弃用接口的信息,请参阅 add_dimension(),已弃用接口

首先将表 conditions 转换为超表,仅对列 time 进行范围分区,然后添加一个额外的分区键,对 location 进行四个分区

SELECT create_hypertable('conditions', by_range('time'));
SELECT add_dimension('conditions', by_hash('location', 4));
注意

by_rangeby_hash 维度构建器是 TimescaleDB 2.13 的新增功能。

将表 conditions 转换为超表,对 time 进行范围分区,然后添加三个额外的维度:一个对 location 进行哈希分区,一个对 time_received 进行范围分区,以及一个对 device_id 进行哈希分区。

SELECT create_hypertable('conditions', by_range('time'));
SELECT add_dimension('conditions', by_hash('location', 2));
SELECT add_dimension('conditions', by_range('time_received', INTERVAL '1 day'));
SELECT add_dimension('conditions', by_hash('device_id', 2));
SELECT add_dimension('conditions', by_hash('device_id', 2), if_not_exists => true);
名称类型默认值必需描述
chunk_time_intervalINTERVAL-每个数据块覆盖的时间间隔。必须 > 0。
dimensionDIMENSION_INFO-要创建 _timescaledb_internal.dimension_info 实例以对超表进行分区,您可以调用 by_rangeby_hash
hypertableREGCLASS-要向其添加维度的超表。
if_not_existsBOOLEANfalse设置为 true 以在列的维度已存在时打印错误。默认情况下会引发异常。
number_partitionsINTEGER-要在 column_name 上使用的哈希分区数。必须 > 0。
partitioning_funcREGCLASS-用于计算值的分区的函数。有关更多信息,请参阅 create_hypertable

要创建 _timescaledb_internal.dimension_info 实例,您可以调用
当您创建超表向现有超表添加维度时,使用 by_rangeby_hash

超表必须始终具有主范围维度,然后是任意数量的额外维度,这些维度可以是范围维度或哈希维度。通常只有一个哈希维度。例如

SELECT create_hypertable('conditions', by_range('time'));
SELECT add_dimension('conditions', by_hash('location', 2));

对于不兼容的数据类型(如 jsonb),您可以为维度构建器的 partition_func 参数指定一个函数,以提取兼容的数据类型。请查看下面的示例部分。

默认情况下,TimescaleDB 为给定的类型调用 PostgreSQL 的内部哈希函数。对于没有原生 PostgreSQL 哈希函数的值类型,您可以使用自定义分区函数。

您可以为范围分区和哈希分区指定自定义分区函数。分区函数应接受 anyelement 参数作为唯一参数,并返回正 integer 哈希值。此哈希值不是分区标识符,而是插入值在维度键空间中的位置,然后将其分布在各个分区中。

创建按范围维度构建器。您可以单独对 by_range 进行分区。

示例

最简单的用法是对时间列进行分区

SELECT create_hypertable('my_table', by_range('time'));

这是默认分区,您无需显式添加它。

如果您的表具有包含时间的非时间列(例如 JSON 列),请添加分区函数以提取时间。

CREATE TABLE my_table (
metric_id serial not null,
data jsonb,
);
CREATE FUNCTION get_time(jsonb) RETURNS timestamptz AS $$
SELECT ($1->>'time')::timestamptz
$$ LANGUAGE sql IMMUTABLE;
SELECT create_hypertable('my_table', by_range('data', '1 day', 'get_time'));
参数
名称类型默认值必需描述
column_nameNAME-要分区的列的名称。
partition_funcREGPROC-用于计算值的分区的函数。
partition_intervalANYELEMENT-要对其列进行分区的时间间隔。

如果要分区的列是

  • TIMESTAMPTIMESTAMPTZDATE:将 partition_interval 指定为 INTERVAL 类型或微秒为单位的整数值。

  • 另一种整数类型:将 partition_interval 指定为反映列的底层语义的整数。例如,如果此列采用 UNIX 时间,请以毫秒为单位指定 partition_interval

分区类型和默认值取决于列类型

列类型分区类型默认值
不带时区的时间戳INTERVAL/INTEGER1 周
带时区的时间戳INTERVAL/INTEGER1 周
日期INTERVAL/INTEGER1 周
SMALLINTSMALLINT10000
INTINT100000
BIGINTBIGINT1000000

哈希分区的主要目的是在同一时间间隔内实现跨多个磁盘的并行化。哈希分区中的每个不同项都哈希到 N 个桶之一。默认情况下,TimescaleDB 使用灵活的范围间隔来管理数据块大小。

您可以在以下场景中使用并行 I/O

  • 两个或多个并发查询应能够并行地从不同的磁盘读取数据。
  • 单个查询应能够使用查询并行化来并行地从多个磁盘读取数据。

对于以下选项

  • RAID:在多个物理磁盘上使用 RAID 设置,并将单个逻辑磁盘公开给超表。即,使用单个表空间。

    最佳实践是在可能的情况下使用 RAID,因为您无需在数据库中手动管理表空间。

  • 多个表空间:对于每个物理磁盘,向数据库添加单独的表空间。TimescaleDB 允许您向单个超表添加多个表空间。但是,在底层,超表的数据块分布在与该超表关联的表空间中。

    当使用多个表空间时,最佳实践是还向超表添加第二个哈希分区的维度,并且每个磁盘至少有一个哈希分区。虽然单个时间维度也有效,但这将意味着第一个数据块写入一个表空间,第二个数据块写入另一个表空间,依此类推,因此只有当查询的时间范围超过单个数据块时才会并行化。

添加哈希分区维度时,将分区数设置为磁盘数的倍数。例如,分区数 P=N*Pd,其中 N 是磁盘数,Pd 是每个磁盘的分区数。这使您以后可以添加更多磁盘并将分区从其他磁盘移动到新磁盘。

TimescaleDB 不会从非常大量的哈希分区中受益,例如您在分区字段中期望的唯一项的数量。非常大量的哈希分区会导致每个分区的负载平衡更差(使用哈希将项目映射到分区),以及某些类型的查询的计划延迟大大增加。

示例
SELECT create_hypertable('conditions', by_range('time'));
SELECT add_dimension('conditions', by_hash('location', 2));
SELECT add_dimension('conditions', by_range('time_received', INTERVAL '1 day'));
参数
名称类型默认值必需描述
column_nameNAME-要分区的列的名称。
partition_funcREGPROC-用于计算值分区的函数。
number_partitionsANYELEMENT-用于 partitioning_column 的哈希分区数。必须大于 0。

by_rangeby-hash 返回一个不透明的 _timescaledb_internal.dimension_info 实例,其中包含此函数使用的维度信息。

类型描述
dimension_idINTEGERTimescaleDB 内部目录中维度的 ID
createdBOOLEAN如果添加了维度,则为 true;当您将 if_not_exists 设置为 true 且未添加维度时,则为 false

关键词

在此页面上发现问题?报告问题 或 在 GitHub 上编辑此页面