云数据库 PostgreSQL timescaledb

这篇说说腾讯云PostgreSQL中timescaledb时序插件,支持将普通表转为超表实现自动分片,提升时序数据写入与聚合查询效率,并说明创建、写入、聚合及分片管理方法。 创建超表:通过create_hypertable将普通表按时间列转换为超表。 时序聚合:使用time_bucket、first/last、histogram等函数进行分桶、首尾值和直方图查询。 分片管理:支持查看、删除过期分片及设置分片时间间隔。

相关产品
云数据库 PostgreSQL 产品页,含版本规格、价格与购买入口。

这里说明 timescaledb 插件的简介及使用方法。

一、概述

timescaledb 是时序数据库插件,将普通表扩展为按时间自动分片的超表,支持高效写入和时序聚合查询,适用于监控、物联网、金融行情等时序场景。

二、支持版本

PostgreSQL 版本 内核版本
PostgreSQL 10 v10.23_r1.20及以上
PostgreSQL 11 v11.22_r1.35及以上
PostgreSQL 12 v12.22_r1.37及以上
PostgreSQL 13 v13.22_r1.32及以上
PostgreSQL 14 v14.22_r1.42及以上
PostgreSQL 15 v15.14_r1.27及以上
PostgreSQL 16 v16.14_r1.26及以上
PostgreSQL 17 v17.10_r1.22及以上
PostgreSQL 18 v18.3_r1.6及以上

注意:说明:

注意:你可在控制台实例详情页查看当前实例的内核版本,或执行 SHOW tencentdb_version; 查询。

三、插件简介

timescaledb 在 PostgreSQL 的基础上提供时序数据管理能力:通过超表(hypertable)将数据按时间自动切分为多个分片(chunk),配合时间分桶函数(time_bucket)进行时序聚合,并提供首尾值、直方图等时序聚合函数,提升时序数据的写入和查询性能。

五、加载插件

timescaledb 是需要预加载的插件,使用前请先在控制台参数设置的 shared_preload_libraries 参数中勾选 timescaledb,保存后重启实例。参数设置方法可参考 设置实例参数。

六、创建扩展

连接到需要使用的数据库,执行以下语句创建扩展:

postgres=> CREATE EXTENSION timescaledb;CREATE EXTENSION

七、创建超表

先创建普通表,再使用 create_hypertable 将其转换为超表,第二个参数为时间列:

postgres=> CREATE TABLE metrics ( time timestamptz NOT NULL, device_id int, temperature float);CREATE TABLEpostgres=> SELECT create_hypertable('metrics', 'time'); create_hypertable———————- (1,public,metrics,t)(1 row)

返回结果中的 t 表示超表创建成功。

八、写入时序数据

向超表写入数据的方式与普通表一致:

postgres=> INSERT INTO metricsSELECT now() – interval '1 hour' * i, i % 3, 20 + (i % 10)FROM generate_series(0, 500) AS i;INSERT 0 501

十、按时间分桶

使用 time_bucket 函数按时间分桶进行聚合。以下示例按天统计温度的平均值:

postgres=> SELECT time_bucket('1 day', time) AS day, count(*) AS cnt, round(avg(temperature)::numeric, 2) AS avg_tempFROM metrics GROUP BY day ORDER BY day LIMIT 7; day | cnt | avg_temp————————+—–+———- 2026-08-13 08:00:00+08 | 12 | 24.50 2026-08-14 08:00:00+08 | 24 | 24.83 2026-08-15 08:00:00+08 | 24 | 24.17 2026-08-16 08:00:00+08 | 24 | 24.75 2026-08-17 08:00:00+08 | 24 | 24.50 2026-08-18 08:00:00+08 | 24 | 24.25 2026-08-19 08:00:00+08 | 24 | 24.83(7 rows)

注意:说明:

注意:time_bucket 默认按 UTC 时区分桶,在中国时区(UTC+8)下,按天分桶的边界为每天08:00。如需按本地时区聚合,请先设置会话时区,例如 SET timezone = 'Asia/Shanghai';。

十一、首尾值

使用 first 和 last 函数获取分组内按时间排序的首尾值:

postgres=> SELECT first(temperature, time) AS first_temp, last(temperature, time) AS last_tempFROM metrics WHERE device_id = 0; first_temp | last_temp————+———– 28 | 20(1 row)

注意:说明:

注意:first(temperature, time) 返回该组内时间最早的温度值,last(temperature, time) 返回时间最晚的值。

十二、直方图

使用 histogram 函数按区间统计数值分布:

postgres=> SELECT histogram(temperature, 0, 30, 5) FROM metrics; histogram——————— {0,0,0,0,201,300,0}(1 row)

注意:说明:

注意:histogram(value, min, max, nbuckets) 将 [min, max] 等分为 nbuckets 个桶,并返回长度为 nbuckets+2 的数组:第1个元素为小于 min 的计数(下溢),最后1个元素为大于 max 的计数(上溢),中间 nbuckets 个为各桶计数。上述结果中501条数据分别落在两个温度区间,其中201条落在18至24度区间、300条落在24至30度区间。

十四、查看分片

使用 show_chunks 函数查看超表的分片:

postgres=> SELECT show_chunks('metrics'); show_chunks—————————————- _timescaledb_internal._hyper_1_1_chunk _timescaledb_internal._hyper_1_2_chunk _timescaledb_internal._hyper_1_3_chunk _timescaledb_internal._hyper_1_4_chunk(4 rows)

注意:说明:

注意:数据按时间自动切分为4个 chunk。

十五、查看分片大小

使用 chunks_detailed_size 函数查看各分片占用的空间:

postgres=> SELECT chunk_name, total_bytes FROM chunks_detailed_size('metrics') ORDER BY chunk_name; chunk_name | total_bytes——————+————- _hyper_1_1_chunk | 24576 _hyper_1_2_chunk | 57344 _hyper_1_3_chunk | 57344 _hyper_1_4_chunk | 24576(4 rows)

十六、删除过期分片

使用 drop_chunks 函数删除指定时间之前的分片:

postgres=> SELECT drop_chunks('metrics', older_than => now() – interval '2 days'); drop_chunks—————————————- _timescaledb_internal._hyper_1_3_chunk _timescaledb_internal._hyper_1_4_chunk(2 rows)

函数返回被删除的分片列表。删除后再查看剩余分片:

postgres=> SELECT show_chunks('metrics'); show_chunks—————————————- _timescaledb_internal._hyper_1_1_chunk _timescaledb_internal._hyper_1_2_chunk(2 rows)

十七、设置分片时间间隔

使用 set_chunk_time_interval 函数设置超表的分片时间跨度:

postgres=> SELECT set_chunk_time_interval('metrics', interval '1 day'); set_chunk_time_interval————————-(1 row)

注意:说明:

注意:设置后,后续新写入的数据将按每天一个 chunk 的粒度切分;已存在的 chunk 保持原间隔不变。合理的分片间隔可兼顾写入性能与查询效率。

十八、多维度分区

对于既需要按时间、又需要按其他维度(如设备、地域)分区查询的场景,可使用 add_dimension 添加空间分区:

postgres=> CREATE TABLE tracking ( time timestamptz NOT NULL, location_id int, temp float);CREATE TABLEpostgres=> SELECT create_hypertable('tracking', 'time'); create_hypertable———————– (2,public,tracking,t)(1 row)postgres=> SELECT add_dimension('tracking', 'location_id', number_partitions => 4); add_dimension———————————– (3,public,tracking,location_id,t)(1 row)

查看维度信息:

postgres=> SELECT dimension_number, column_name, dimension_type, num_partitionsFROM timescaledb_information.dimensions WHERE hypertable_name = 'tracking' ORDER BY dimension_number; dimension_number | column_name | dimension_type | num_partitions——————+————-+—————-+—————- 1 | time | Time | 2 | location_id | Space | 4(2 rows)

注意:说明:

注意:超表现在按 time 时间维度和 location_id 空间维度进行分区,location_id 被划分为4个分区。

20、查看超表大小

使用 hypertable_size 函数查看超表占用的空间:

postgres=> SELECT pg_size_pretty(hypertable_size('metrics')) AS size; size——- 88 kB(1 row)

21、查看超表元数据

通过 timescaledb_information.hypertables 视图查看超表信息:

postgres=> SELECT hypertable_name, num_chunks, compression_enabledFROM timescaledb_information.hypertables WHERE hypertable_name = 'metrics'; hypertable_name | num_chunks | compression_enabled—————–+————+——————— metrics | 2 | f(1 row)

注意:说明:

注意:删除过期分片后,num_chunks 为2,与 show_chunks 的结果一致。

23、Q:创建扩展时报 must be preloaded?

A:timescaledb 需要预加载。请在控制台参数设置的 shared_preload_libraries 参数中勾选 timescaledb,保存并重启实例后再创建扩展。

24、Q:连续聚合(continuous aggregate)、压缩(compression)、保留策略(retention policy)不可用?

A:腾讯云提供的 timescaledb 为 Apache 2.0版本,连续聚合、压缩、数据保留策略等 Timescale License 功能不在支持范围内,使用时会提示 not supported under the current "apache" license。

25、相关参考

timescaledb 产品文档

赞 (0)
上一篇 4天前
下一篇 4天前