postgresql - 将 PostgreSQL 表转换为 TimescaleDB 超表

标签 postgresql timescaledb

我有一个 PostgreSQL 表,我正在尝试将其转换为 TimescaleDB 超表。
该表如下所示:

CREATE TABLE public.data
(
    event_time timestamp with time zone NOT NULL,
    pair_id integer NOT NULL,
    entry_id bigint NOT NULL,
    event_data int NOT NULL,
    CONSTRAINT con1 UNIQUE (pair_id, entry_id ),
    CONSTRAINT pair_id_fkey FOREIGN KEY (pair_id)
        REFERENCES public.pairs (id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
)
当我尝试使用以下命令将此表转换为 TimescaleDB 超表时:
SELECT create_hypertable(
        'data',
        'event_time',
        chunk_time_interval => INTERVAL '1 hour',
        migrate_data => TRUE
);
我收到错误:ERROR: cannot create a unique index without the column "event_time" (used in partitioning) 问题一:来自这篇文章 How to convert a simple postgresql table to hypertable or timescale db table using created_at for indexing我的理解是,这是因为我指定了一个唯一约束 (pair_id_fkey),它不包含我正在分区的列 - event_time。那是对的吗?
问题2:我应该如何更改我的 table 或 hypertable 以便能够转换它?我已经添加了一些关于我计划如何使用数据和下面数据结构的数据。
数据属性和用法:
  • 可以有多个具有相同 event_time 的条目 - 这些条目将具有按顺序排列的 entry_id
  • 这意味着如果我有 2 个条目 (event_time 2021-05-18::10:16, id 105, ) 和 (event_time 2021-05-18::10:16, id 107, ) 那么id 为 106 的条目也会有 event_time 2021-05-18::10:16

  • entry_id 不是我生成的,我使用唯一约束 con1 来确保我没有插入重复数据
  • 我将主要在 event_time 上查询数据,例如创建绘图和执行其他分析
  • 此时数据库包含大约 46 亿行,但很快就会包含更多行
  • 我想利用 TimescaleDB 的速度和良好的压缩性
  • 我不太关心插入性能

  • 我一直在考虑的解决方案:
  • 以某种方式将所有具有相同时间戳的事件打包到一个数组中,并将它们放在一行中。我认为这会对压缩产生不利影响,并在查询数据时提供较少的灵活性。此外,我可能最终不得不解压缩每个查询的数据。
  • 删除唯一约束 con1 - 那么我如何确保不会两次添加同一行?
  • 扩展唯一约束 con1 以包含 event_time - 这不会以某种方式降低性能,同时打开错误,其中我不小心插入了具有 entry_id 和 pair_id 但不同 event_time 的 2 行? (虽然我怀疑这是可能发生的事情)
  • 最佳答案

    您正确理解 UNIQUE (pair_id, entry_id )不允许从表创建超表,因为唯一约束需要包含分区键,即 event_time在你的情况下。

  • 我不遵循第一个选项,其中具有相同时间戳的记录被打包到单个记录中,将如何帮助唯一性。
  • 删除唯一约束将允许创建超表,正如您提到的,您将失去检查约束的可能性。
  • 添加时间列,例如,UNIQUE (pair_id, entry_id, event_time)是一种很常见的方法,但它允许插入您提到的具有不同时间戳的重复项。在插入过程中,它的性能将比选项 2 差。您可以替换 event_time 上的索引(这是您需要的,因为您在此列上进行查询,并且它是由 TimescaleDB 自动创建的)与 unique index ,所以你可以节省一点,例如,

  • CREATE UNIQUE INDEX indx ON (event_time, pair_id, entry_id);
    
  • 在每个块表上手动创建唯一约束。这将保证块内的唯一性,但仍然可能在不同的块中存在重复项。主要缺点是您需要弄清楚在创建新块时如何创建它。

  • TimescaleDB 不支持没有分区键的唯一约束,因为它需要访问所有现有块来检查唯一性,这会降低性能。 (或者它需要创建一个可能很大的全局索引)我认为时间序列数据具有唯一约束并不常见,因为它通常与人工生成的基于计数器的标识符有关。

    关于postgresql - 将 PostgreSQL 表转换为 TimescaleDB 超表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67582526/

    相关文章:

    timescaledb - TimescaleDB 未找到函数 add_compression_policy

    ruby-on-rails - 如何筛选 Rails 模型中太大的整数?

    sql - PostgreSQL,不同,排序依据和括号

    postgresql - 如何使用 ecto 查询表达式在 3 个表之间连接和过滤

    sql - 时间刻度数据库/Postgres : INSERT ON CONFLICT KEEP MAXIMUM

    sql - 没有行的 Timescaledb time_bucket 获取周期

    postgresql - 组织.postgresql.util.PSQLException : "The server does not support SSL" despite ssl=false in jdbc uri

    php - 多语言翻译模块的数据库模型

    python - 我如何使用 psycopg2 创建物化 View ?

    sql - Postgres : Get value of a column corresponding to max of other column in a group