错误:不能在没有列“date_time”的情况下创建唯一索引(用于分区)

Jun*_*rat 3 postgresql timescaledb

我刚开始在 postgresql 中使用timescaleDB。我有一个名为的数据库storage_db,其中包含一个名为day_ahead_prices.

安装 timescaledb 后,我跟随Migrate 从同一个 postgresql 数据库迁移storage_db到 timescaledb。

当我这样做时(包括索引):

CREATE TABLE tsdb_day_ahead_prices (LIKE day_ahead_prices INCLUDING DEFAULTS INCLUDING CONSTRAINTS INCLUDING INDEXES);
select create_hypertable('tsdb_day_ahead_prices', 'date_time');
Run Code Online (Sandbox Code Playgroud)

它给了我以下错误:

ERROR:  cannot create a unique index without the column "date_time" (used in partitioning)
Run Code Online (Sandbox Code Playgroud)

但是当我这样做时(索引排除):

CREATE TABLE tsdb_day_ahead_prices (LIKE day_ahead_prices INCLUDING DEFAULTS INCLUDING CONSTRAINTS EXCLUDING INDEXES);
select create_hypertable('tsdb_day_ahead_prices', 'date_time');
Run Code Online (Sandbox Code Playgroud)

它成功了。接下来,我做了

select create_hypertable('tsdb_day_ahead_prices', 'date_time');
Run Code Online (Sandbox Code Playgroud)

它给了我以下输出:

         create_hypertable          
------------------------------------
 (3,public,tsdb_day_ahead_prices,t)
(1 row)
Run Code Online (Sandbox Code Playgroud)

我对此有点陌生,所以任何人都可以向我解释它们之间有什么区别,为什么我在第一种情况下会出错?

PS:

我的day_ahead_prices样子如下:

 id | country_code | values  |         date_time          
----+--------------+---------+----------------------------
  1 | LU           | 100.503 | 2020-04-11 14:04:30.461605
  2 | LU           | 100.503 | 2020-04-11 14:18:39.600574
  3 | DE           |  106.68 | 2020-04-11 15:59:10.223965
Run Code Online (Sandbox Code Playgroud)

编辑1:

我使用and创建了day_ahead_prices表,代码是:pythonflaskflask_sqlalchemy

class day_ahead_prices(db.Model):
    __tablename__ = "day_ahead_prices"
    id = db.Column(db.Integer, primary_key=True)
    country_code = db.Column(avail_cc_enum, nullable=False)
    values = db.Column(db.Float(precision=2), nullable=False)
    date_time = db.Column(db.DateTime, default=datetime.now(tz=tz), nullable=False)

    def __init__(self, country_code, values):
        self.country_code = country_code
        self.values = values
Run Code Online (Sandbox Code Playgroud)

Bla*_*ski 8

执行时,CREATE TABLE tsdb_day_ahead_prices (LIKE day_ahead_prices INCLUDING DEFAULTS INCLUDING CONSTRAINTS INCLUDING INDEXES);您告诉数据库tsdb_day_ahead_prices使用day_ahead_prices作为模板(相同的列,这些列的相同类型)创建表,但您还告诉它包括您在原始表,并为您的新表应用/创建相同的表。

然后您正在执行使tsdb_day_ahead_prices表成为超表的 timescaledb 命令。超表是一种抽象,它隐藏了物理表的分区。(https://www.timescale.com/products/how-it-works)。您告诉tsdb_day_ahead_pricesTimescaleDB 使用该date_time列作为分区键来制作超表。

创建超表时,TimescaleDB 强加的一个限制是分区列(在您的情况下为“date_time”)必须包含在该表的任何唯一索引(和主键)中。(https://docs.timescale.com/latest/using-timescaledb/schema-management#indexing-best-practices

你得到的第一个错误cannot create a unique index without the column "date_time"正是因为这个。您复制了id列上的主键定义。所以主键是防止表成为超级表。

第二次,您创建了tsdb_day_ahead_prices表,但没有从原始表中复制索引,因此未定义主键(实际上是唯一索引)。这样hypertable的创建就成功了。

您从 create_hypertable 函数获得的输出告诉您,您有一个新的超表,在公共模式中,超表的名称以及 timescaledb 用于它的内部 ID。

所以现在你可以tsdb_day_ahead_prices正常使用,下面的 timescaledb 将确保数据进入正确的分区/块

该表的 id 是否需要唯一?如果您要保留时间序列数据,那么每一行对于每个 id 可能并不是唯一的,但可能在给定时间由 id 唯一标识。

您可以创建一个单独的表,你确定的项目 items(id PRIMARY KEY, country_code)和有Hypertable的BE day_ahead_prices(time, value, item_id REFERENCES items(id))

  • 单独的表还有助于减少存储空间。还要检查时间尺度压缩和连续聚合 (2认同)