TimescaleDB中的超表(Hypertable)被设计为易于管理,并且对于熟悉标准PostgreSQL表的用户具有可预测性。在TimescaleDB中创建、修改或删除超表的SQL命令与PostgreSQL中的命令相同。即超表由许多相互链接的“块”表组成,对超级表执行的命令也会自动将更改传播到属于该超级表的所有“块”表。

创建超表 Create a Hypertable

创建一个超表(Hypertable)需要两个步骤

  1. 创建一个标准表 (PostgreSQL docs)。

    1. CREATE TABLE conditions (
    2. time TIMESTAMPTZ NOT NULL,
    3. location TEXT NOT NULL,
    4. temperature DOUBLE PRECISION NULL
    5. );
  2. 对刚创建的表执行 TimescaleDB create_hypertable 命令。

TIP: 如果你需要将已存在的表迁移为超表,确保使用这个方法时设置 migrate_data 参数为 true 。如果您希望更好地控制索引的形成以及超表的其他方面,请查看这些迁移说明。

WARNING: 使用 migrate_data 迁移一个非空表可能会长时间锁定这个表(锁定时间取决于表大小)

TIP: create_hypertable 函数中使用的“时间”列支持时间戳,日期或整数类型,因此您可以使用基于时间的参数,只要它可以递增即可。 例如,单调递增的id也是有效的。

修改超表 Alter a Hypertable

你可以在超表上执行标准的 ALTER TABLE 指令 (PostgreSQL docs)。

ALTER TABLE conditions
  ADD COLUMN humidity DOUBLE PRECISION NULL;


TimescaleDB将自动将这些架构更改传播到构成此超表的块中。

WARNING: 如果对应表附加列的默认值为NULL,则修改这个表架构将非常有效。 如果默认值设置为非null值,则TimescaleDB将需要为属于该超表的所有行(所有块)填充该值。

删除超表 Deleting a Hypertable

仅需使用标准的 DROP TABLE 指令,TimescaleDB将自动的删除属于超表的所有块。

DROP TABLE conditions;

最佳实践

TimescaleDB的用户一般有两个问题

  1. 我应该为时间间隔(Time intervals)配置多长时间?
  2. 我应该使用空间分区吗?应该使用多少个空间分区?

时间间隔(Time intervals) 用户可以使用默认的时间间隔,从v0.11.0开始的7天和v0.11.0之前的1个月。 另外,用户可以在创建超表时通过设置 chunk_time_interval 显式配置时间间隔。创建超表之后,可以通过调用 set_chunk_time_interval 更改用于新块的间隔。

选择时间间隔的关键在于最新的时间间隔块(包括索引)(或是空间分区的块)与内存匹配。 因此,我们通常建议设置时间间隔,以使这些块占主内存的比例不超过25%。

TIP:确保您所计划的超表中的单个块都匹配主内存的25%,而不是超表去匹配内存的25%。

为了保证这一点,您需要对数据增长速率有一个大致的了解。 如果您往64GB内存的实例每天写大约2GB的数据,那么将时间间隔设置为一周将是不错的选择。 如果您每天在同一台计算机上写入10GB,则将时间间隔设置为一天会比较合适。 如果要分批加载更多数据,例如,您每周批量加载70GB数据,并且该数据对应于整周的记录,则此间隔也可保持不变。

虽然通常将块做成较小而不是太大是比较安全的,但是将间隔设置得太小会导致产生很多块(chunk),这对于某些类型的查询增加计划时间。

TIP: 一个警告是块大小实际上取决于基础数据大小和块的所有索引,因此如果您大量使用复杂的索引类型(例如某些PostGIS地理空间索引),则需要格外小心。 在测试期间,您可以通过 chunk_relation_size 函数检查总块大小。



空间分区(Space partitions): 附加分区使用在非常特定的场景下。 绝大多数用户不需要使用它
**
空间分区使用哈希:每个不同的数据都哈希到N个存储桶中的某一个。 请记住,我们已经在使用(灵活的)时间间隔来管理块大小; 空间分区的主要目的是使并行I/O具有相同的时间间隔。

并行I/O可以在两种情况下受益:(a)两个或多个并发查询应该能够从不同的磁盘并行读取,或者(b)一个查询应该能够使用查询并行化从多个磁盘并行读取 。

请注意,PostgreSQL 9.6(和10)中的查询并行化不支持并行查询不同的超表块。 查询并行化仅适用于单个物理表(因此适用于单个块)。 我们可能对此添加自己的支持,但是当前不支持。

因此,寻找并行I/O的用户有两个选择:

1.在多个物理磁盘上使用RAID设置,并将单个逻辑磁盘暴露给超级表(即,通过单个表空间)。
2.对于每个物理磁盘,向数据库添加一个单独的表空间。 TimescaleDB允许您实际上将多个表空间添加到单个超级表中(尽管在底层,每个基础块都将由TimescaleDB映射到单个表空间/物理磁盘上)。

我们建议您尽可能使用RAID设置,因为它支持上述两种形式的并行化(即,对独立磁盘的单独查询,对并行多个磁盘的单个查询)。多表空间方法仅支持前者。使用RAID设置时,不需要空间分区。

也就是说,在使用空间分区时,我们建议每个磁盘使用1个空间分区。

TimescaleDB不能从大量的空间分区(例如,您希望在分区字段中获得的唯一项的数量)中受益。如此大量的分区导致较差的每个分区负载平衡(使用散列将项目映射到分区),以及导致某些类型的查询计划时间大大增加。