您可以在超表上使用唯一索引来强制约束。您不需要在超表上创建唯一索引。当您创建唯一索引时,它必须包含超表的所有分区列。

注意

如果您有主键,您就拥有唯一索引。在 PostgreSQL 中,主键是具有 NOT NULL 约束的唯一索引。

要在超表上创建唯一索引

  1. 确定您的分区列
  2. 创建包含所有这些列的唯一索引,并可选择添加其他列

在创建唯一索引之前,您需要确定超表上允许哪些唯一索引。首先确定您的分区列。

Timescale 传统上使用以下列来分区超表

  • 用于创建超表的 time 列。每个 Timescale 超表都按时间分区。
  • 任何空间分区列。空间分区是可选的,并非包含在每个超表中。如果您在创建超表时指定了 partitioning_column 参数,则您拥有空间分区列。

当您在超表上创建唯一索引时,它必须包含您之前确定的所有分区列。它也可以包含其他列,并且它们可以以任何顺序排列。

注意

此限制是保证索引中全局唯一性所必需的。

使用 CREATE UNIQUE INDEX 命令创建唯一索引。确保在索引中包含所有分区列。如果需要,您也可以包含其他列。

例如,对于名为 hypertable_example 的超表,按 timedevice_id 分区,在 timedevice_id 上创建索引

CREATE UNIQUE INDEX idx_deviceid_time
ON hypertable_example(device_id, time);

您还可以在 timeuser_iddevice_id 上创建唯一索引。请注意,device_id 不是分区列,但这仍然有效

CREATE UNIQUE INDEX idx_userid_deviceid_time
ON hypertable_example(user_id, device_id, time);

您不能在没有 time 的情况下创建唯一索引,因为 time 是分区列。例如,这不起作用

-- This gives you an error
CREATE UNIQUE INDEX idx_deviceid
ON hypertable_example(device_id);

您会收到错误

ERROR: cannot create a unique index without the column "<COLUMN_NAME>" (used in partitioning)

通过将 time 添加到您的唯一索引来修复错误。

如果您在将表转换为超表之前在该表上创建唯一索引,则相同的限制反向适用。您只能按唯一索引中的列对表进行分区。

  1. 创建您的表。例如

    CREATE TABLE hypertable_example(
    time TIMESTAMPTZ,
    user_id BIGINT,
    device_id BIGINT,
    value FLOAT
    );
  2. 在表上创建唯一索引。在本例中,索引位于 device_idtime

    CREATE UNIQUE INDEX idx_deviceid_time
    ON hypertable_example(device_id, time);
  3. 将表转换为仅按 time 分区的超表

    SELECT * from create_hypertable('hypertable_example', by_range('time'));

    或者,将表转换为按 timedevice_id 分区的超表

    SELECT * FROM create_hypertable('hypertable_example', by_range('time'));
    SELECT * FROM add_dimension('hypertable_example', by_hash('device_id', 4));

您不能将表转换为按 timeuser_id 分区的超表,因为 user_id 不是唯一索引的一部分。 这不起作用

-- This gives you an error
SELECT * FROM create_hypertable('hypertable_example', by_range('time'));
SELECT * FROM add_dimension('hypertable_example', by_hash('user_id', 4));

您会收到错误

ERROR: cannot create a unique index without the column "<COLUMN_NAME>" (used in partitioning)

请注意,错误是由创建索引引起的,而不是由创建超表引起的。发生这种情况是因为 Timescale 在将表转换为超表后会重新创建索引。

通过将 user_id 添加到您的唯一索引来修复错误。

关键词

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