> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-mintlify-fbfa8bee.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> 一种用于存储时间序列的表引擎，即一组与时间戳和标签（或标记）相关联的值。

# TimeSeries 表引擎

export const CloudNotSupportedBadge = () => {
  return <div className="cloudNotSupportedBadge">
            <div className="cloudNotSupportedIcon">
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path strokeWidth="1.5" d="M6.33366 12.6666L12.3739 12.6667C13.6593 12.6667 14.7073 11.6187 14.7073 10.3334C14.7073 9.04804 13.6593 8.00003 12.3739 8.00003C12.3739 8.00003 12.3337 7.66659 12.0003 7.33325M10.667 5.33322C8.00033 2.33325 4.45395 4.78537 4.14195 6.68203C2.55728 6.7627 1.29395 8.06203 1.29395 9.6667C1.29395 11.3234 2.66699 12.6666 4.00033 12.6666" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
                <path strokeWidth="1.5" d="M2.66699 14L12.0003 4.66663" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
            </svg>

        </div>
            ClickHouse Cloud 不支持此功能
        </div>;
};

export const ExperimentalBadge = () => {
  return <div className="experimentalBadge">
            <div className="experimentalIcon">
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path strokeWidth="1.25" d="M5.5 2H10.5" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
                <path strokeWidth="1.25" d="M9.50015 2V6.19625L13.4283 12.7425C13.4738 12.8183 13.4985 12.9049 13.4996 12.9934C13.5008 13.0818 13.4785 13.169 13.435 13.246C13.3914 13.323 13.3283 13.3871 13.2519 13.4317C13.1755 13.4764 13.0886 13.4999 13.0002 13.5H3.00015C2.91164 13.5 2.8247 13.4766 2.74822 13.432C2.67174 13.3874 2.60847 13.3233 2.56487 13.2463C2.52126 13.1693 2.49889 13.082 2.50004 12.9935C2.50119 12.905 2.52582 12.8184 2.5714 12.7425L6.50015 6.19625V2" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
                <path strokeWidth="1.25" d="M4.47656 9.56754C5.30344 9.41254 6.47656 9.47942 7.99969 10.25C10.0153 11.2707 11.4216 11.0569 12.2184 10.7282" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
            </svg>
        </div>
            Experimental 功能。 <u><a href="/docs/beta-and-experimental-features#experimental-features">了解详情。</a></u>
        </div>;
};

一种用于存储时间序列的表引擎，即一组与时间戳和标签 (或标记) 关联的值：

```sql theme={null}
metric_name1[tag1=value1, tag2=value2, ...] = {timestamp1: value1, timestamp2: value2, ...}
metric_name2[...] = ...
```

<Info>
  这是一个 Experimental 功能，未来的发行版中可能会发生不向后兼容的变更。
  使用 [allow\_experimental\_time\_series\_table](/zh/reference/settings/session-settings#allow_experimental_time_series_table) 设置
  启用 TimeSeries 表引擎。
  输入命令 `set allow_experimental_time_series_table = 1`。
</Info>

<div id="syntax">
  ## 语法
</div>

```sql theme={null}
CREATE TABLE name [(columns)] ENGINE=TimeSeries
[SETTINGS var1=value1, ...]
[SAMPLES db.samples_table_name | [SAMPLES INNER COLUMNS (...)] [SAMPLES INNER ENGINE engine(arguments)]]
[TAGS db.tags_table_name | [TAGS INNER COLUMNS (...)] [TAGS INNER ENGINE engine(arguments)]]
[METRICS db.metrics_table_name | [METRICS INNER COLUMNS (...)] [METRICS INNER ENGINE engine(arguments)]]
```

<Note>
  关键字 `SAMPLES` 有一个别名 `DATA`，保留它是为了保持向后兼容性。
</Note>

<div id="usage">
  ## 用法
</div>

一开始先使用默认设置会更简单 (可以在不指定列列表的情况下创建 `TimeSeries` 表) ：

```sql theme={null}
CREATE TABLE my_table ENGINE=TimeSeries
```

随后，该表可与以下协议配合使用 (必须在服务器配置中分配端口) ：

* [Prometheus remote-write](/zh/concepts/features/interfaces/prometheus#remote-write)
* [Prometheus remote-read](/zh/concepts/features/interfaces/prometheus#remote-read)

<div id="outer-columns">
  ### 外部列
</div>

TimeSeries 表的列会自动生成。这些列属于外部列，不存储任何数据，只为 SELECT/INSERT 提供接口。实际数据存储在[目标表](#target-tables)中。以下是外部列列表：

| Name            | Type                                        | Description                                                                                                                             |
| --------------- | ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `metric_name`   | `String`                                    | 指标名称                                                                                                                                    |
| `tags`          | `Map(String, String)`                       | 时间序列的标签映射 (标记)                                                                                                                          |
| `time_series`   | `Array(Tuple(DateTime64(3), Float64))` (默认) | 时间序列的 (timestamp, value) 对数组。该 Tuple 的 timestamp 和 scalar 元素类型可从 samples `INNER COLUMNS` 声明中推导得出 (参见[指定外部列](#specifying-outer-columns)) |
| `metric_family` | `String`                                    | 指标族名称 (用于指标元数据)                                                                                                                         |
| `type`          | `String`                                    | 指标类型 (例如 "counter"、"gauge")                                                                                                             |
| `unit`          | `String`                                    | 指标单位                                                                                                                                    |
| `help`          | `String`                                    | 指标说明                                                                                                                                    |

示例：

```sql theme={null}
INSERT INTO my_table (metric_name, tags, time_series) VALUES
    ('cpu_usage', {'job': 'node_exporter', 'instance': 'host1:9100'},
     [(toDateTime64('2024-01-01 00:00:00', 3), 0.5), (toDateTime64('2024-01-01 00:01:00', 3), 0.7)])
```

在插入时，`metric_name` 可以为空，这表示指标名称是在 `tags` 的 `__name__` 中指定的，例如：

```sql theme={null}
INSERT INTO my_table (tags, time_series) VALUES
    ({'__name__': 'cpu_usage', 'job': 'test'},
     [(toDateTime64('2024-01-01 00:00:00', 3), 0.5)])
```

要插入指标元数据，请写入 `metric_family`、`type`、`unit` 和 `help` 列：

```sql theme={null}
INSERT INTO my_table (metric_name, tags, time_series, metric_family, type, unit, help) VALUES
    ('http_requests_total', {'method': 'GET'}, [(now64(), 100.0)],
     'http_requests_total', 'counter', 'requests', 'Total HTTP requests')
```

<div id="specifying-outer-columns">
  ### 指定外部列
</div>

可以在 `CREATE TABLE` 语句中显式列出外部 `time_series` 列，以覆盖其默认的 `Array(Tuple(DateTime64(3), Float64))` 类型。ClickHouse 会从该元组中提取时间戳类型和值类型，并将它们传递到内部样本表：

```sql theme={null}
CREATE TABLE my_table (time_series Array(Tuple(UInt32, Float32))) ENGINE=TimeSeries
```

这相当于直接在 samples 的 `INNER COLUMNS` 子句中声明时间戳列和值列的类型：

```sql theme={null}
CREATE TABLE my_table ENGINE=TimeSeries
SAMPLES INNER COLUMNS (timestamp UInt32, value Float32)
```

如果在同一条 `CREATE TABLE` 语句中同时使用这两种形式，则声明的类型必须一致。

<div id="target-tables">
  ## 目标表
</div>

`TimeSeries` 表本身不存储数据，所有数据都保存在其目标表中。
这与 [materialized view](/zh/reference/statements/create/view#materialized-view) 的工作方式类似，
区别在于 materialized view 只有一个目标表，
而 `TimeSeries` 表有三个目标表，分别名为 [samples](#samples-table)、[标签](#tags-table) 和 [metrics](#metrics-table)。

这些目标表既可以在 `CREATE TABLE` 查询中显式指定，
也可以由 `TimeSeries` 表引擎自动生成内部目标表。

插入 `TimeSeries` 表的行会被转换、拆分为块，并写入这三个目标表。

目标表如下：

<div id="samples-table">
  ### Samples 表
</div>

*samples* 表包含与某个标识符关联的时间序列。

*samples* 表必须包含以下列：

| 名称          | 必填？  | 默认类型            | 可选类型                  | 描述                 |
| ----------- | ---- | --------------- | --------------------- | ------------------ |
| `id`        | \[x] | `UUID`          | any                   | 标识一组指标名称和标签的组合     |
| `timestamp` | \[x] | `DateTime64(3)` | `DateTime64(X)`       | 一个时间点              |
| `value`     | \[x] | `Float64`       | `Float32` 或 `Float64` | 与 `timestamp` 关联的值 |

<div id="tags-table">
  ### 标签表
</div>

*tags* 表包含针对每种指标名称与标签组合计算出的标识符。

*tags* 表必须包含以下列：

| 名称                   | 必填？  | 默认类型                                  | 可能的类型                                                                                                                 | 描述                                                                                    |
| -------------------- | ---- | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| `id`                 | \[x] | `UUID`                                | any (必须与 [samples](#samples-table) 表中 `id` 的类型匹配)                                                                     | `id` 用于标识一种指标名称与标签的组合。DEFAULT 表达式指定了如何计算该标识符                                          |
| `metric_name`        | \[x] | `LowCardinality(String)`              | `String` 或 `LowCardinality(String)`                                                                                   | 指标名称                                                                                  |
| `<tag_value_column>` | \[ ] | `String`                              | `String` 或 `LowCardinality(String)` 或 `LowCardinality(Nullable(String))`                                              | 特定标签的值；该标签的名称以及对应列的名称在 [tags\_to\_columns](#settings) 设置中指定                           |
| `tags`               | \[x] | `Map(LowCardinality(String), String)` | `Map(String, String)` 或 `Map(LowCardinality(String), String)` 或 `Map(LowCardinality(String), LowCardinality(String))` | 标签映射，不包括表示指标名称的标签 `__name__`，也不包括 [tags\_to\_columns](#settings) 设置中枚举的标签名称           |
| `all_tags`           | \[ ] | `Map(String, String)`                 | `Map(String, String)` 或 `Map(LowCardinality(String), String)` 或 `Map(LowCardinality(String), LowCardinality(String))` | 临时列，每一行都是一个包含所有标签的映射，仅排除表示指标名称的标签 `__name__`。该列的唯一用途是在计算 `id` 时使用                     |
| `min_time`           | \[ ] | `Nullable(DateTime64(3))`             | `DateTime64(X)` 或 `Nullable(DateTime64(X))`                                                                           | 具有该 `id` 的时间序列的最小时间戳。如果 [store\_min\_time\_and\_max\_time](#settings) 为 `true`，则会创建此列 |
| `max_time`           | \[ ] | `Nullable(DateTime64(3))`             | `DateTime64(X)` 或 `Nullable(DateTime64(X))`                                                                           | 具有该 `id` 的时间序列的最大时间戳。如果 [store\_min\_time\_and\_max\_time](#settings) 为 `true`，则会创建此列 |

<div id="metrics-table">
  ### 指标表
</div>

*metrics* 表包含有关已采集指标、其类型及描述的信息。

*metrics* 表必须包含以下列：

| 名称                   | 必需？  | 默认类型                     | 可能的类型                               | 描述                                                                               |
| -------------------- | ---- | ------------------------ | ----------------------------------- | -------------------------------------------------------------------------------- |
| `metric_family_name` | \[x] | `String`                 | `String` 或 `LowCardinality(String)` | 指标族的名称                                                                           |
| `type`               | \[x] | `LowCardinality(String)` | `String` 或 `LowCardinality(String)` | 指标族的类型，可为 "counter"、"gauge"、"summary"、"stateset"、"histogram"、"gaugehistogram" 之一 |
| `unit`               | \[x] | `LowCardinality(String)` | `String` 或 `LowCardinality(String)` | 指标使用的单位                                                                          |
| `help`               | \[x] | `String`                 | `String` 或 `LowCardinality(String)` | 指标的描述                                                                            |

<div id="creation">
  ## 创建
</div>

可以通过多种方式使用 `TimeSeries` 表引擎创建表。
最简单的语句

```sql theme={null}
CREATE TABLE my_table ENGINE=TimeSeries
```

实际上会创建下列表 (可通过执行 `SHOW CREATE TABLE my_table` 查看) ：

```sql theme={null}
CREATE TABLE my_table
(
    `metric_name` String,
    `tags` Map(String, String),
    `time_series` Array(Tuple(DateTime64(3), Float64)),
    `metric_family` String,
    `type` String,
    `unit` String,
    `help` String
)
ENGINE = TimeSeries
SAMPLES INNER COLUMNS
(
    `id` UUID,
    `timestamp` DateTime64(3),
    `value` Float64
)
SAMPLES INNER ENGINE = MergeTree ORDER BY (id, timestamp)
TAGS INNER COLUMNS
(
    `id` UUID DEFAULT reinterpretAsUUID(sipHash128(metric_name, all_tags)),
    `metric_name` LowCardinality(String),
    `tags` Map(LowCardinality(String), String),
    `all_tags` Map(String, String) EPHEMERAL,
    `min_time` SimpleAggregateFunction(min, Nullable(DateTime64(3))),
    `max_time` SimpleAggregateFunction(max, Nullable(DateTime64(3)))
)
TAGS INNER ENGINE = AggregatingMergeTree PRIMARY KEY metric_name ORDER BY (metric_name, id)
METRICS INNER COLUMNS
(
    `metric_family_name` String,
    `type` LowCardinality(String),
    `unit` LowCardinality(String),
    `help` String
)
METRICS INNER ENGINE = ReplacingMergeTree ORDER BY metric_family_name
```

因此，这些列是自动生成的，而且还有三个内部目标表，它们各自的列定义
存储在 `INNER COLUMNS` 子句中。

内部目标表的名称类似于 `.inner_id.samples.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`、
`.inner_id.tags.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`、`.inner_id.metrics.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`，
并且每个目标表都有各自的一组列：

```sql theme={null}
CREATE TABLE default.`.inner_id.samples.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
(
    `id` UUID,
    `timestamp` DateTime64(3),
    `value` Float64
)
ENGINE = MergeTree
ORDER BY (id, timestamp)
```

```sql theme={null}
CREATE TABLE default.`.inner_id.tags.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
(
    `id` UUID DEFAULT reinterpretAsUUID(sipHash128(metric_name, all_tags)),
    `metric_name` LowCardinality(String),
    `tags` Map(LowCardinality(String), String),
    `all_tags` Map(String, String) EPHEMERAL,
    `min_time` SimpleAggregateFunction(min, Nullable(DateTime64(3))),
    `max_time` SimpleAggregateFunction(max, Nullable(DateTime64(3)))
)
ENGINE = AggregatingMergeTree
PRIMARY KEY metric_name
ORDER BY (metric_name, id)
```

```sql theme={null}
CREATE TABLE default.`.inner_id.metrics.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
(
    `metric_family_name` String,
    `type` LowCardinality(String),
    `unit` LowCardinality(String),
    `help` String
)
ENGINE = ReplacingMergeTree
ORDER BY metric_family_name
```

<div id="create-as">
  ## 使用现有表创建表
</div>

语句 `CREATE TABLE new_table AS existing_table` 会从 `existing_table` 复制以下内容：

* `SETTINGS`
* 每种类型的 `INNER COLUMNS`
* 每种类型的 `INNER ENGINE`

如果 `existing_table` 包含外部目标，则不允许使用该语句。
外部列列表会重新生成，而不会被复制。

<div id="adjusting-column-types">
  ## 调整列类型
</div>

你可以使用 `INNER COLUMNS` 子句来调整内部目标表中各列的类型。例如，要将时间戳以微秒存储，并将值存储为 `Float32`：

```sql theme={null}
CREATE TABLE my_table ENGINE=TimeSeries
SAMPLES INNER COLUMNS (timestamp DateTime64(6), value Float32)
```

同一子句也可用于指定编解码器及其他列属性：

```sql theme={null}
CREATE TABLE my_table ENGINE=TimeSeries
SAMPLES INNER COLUMNS (timestamp DateTime64(3) CODEC(DoubleDelta))
```

<div id="id-column">
  ## `id` 列
</div>

`id` 列包含标识符；每个标识符都是根据某个指标名称与标签的组合计算得出的。
用于生成标识符的类型和 `DEFAULT` 表达式可通过 `TAGS INNER COLUMNS` 子句自定义：

```sql theme={null}
CREATE TABLE my_table ENGINE=TimeSeries
TAGS INNER COLUMNS (id UInt64 DEFAULT sipHash64(metric_name, all_tags))
```

The `id` 列的类型必须是 `UUID`、`UInt64`、`UInt128` 或 `FixedString(16)` 之一。如果未提供 `DEFAULT` 表达式，ClickHouse 会根据 `id` 类型自动选择。samples 和 tags 内部表中声明的 `id` 类型必须保持一致。

`id_generator` 设置也支持相同的自定义，而无需使用 `INNER COLUMNS` 子句：

```sql theme={null}
CREATE TABLE my_table ENGINE=TimeSeries
SETTINGS id_generator = 'sipHash64(metric_name, all_tags)'
```

如果设置了此项，即使该列的 `DEFAULT` 包含其他表达式，也会用它来生成 `id`。

<div id="tags-and-all-tags">
  ## `tags` 和 `all_tags` 列
</div>

有两列包含标签的 Map：`tags` 和 `all_tags`。在这个示例中，它们的含义相同；但如果使用 `tags_to_columns` 设置，
它们也可能不同。此设置允许指定将某个特定标签存储在单独的列中，而不是存储
在 `tags` 列中的 Map 内：

```sql theme={null}
CREATE TABLE my_table
ENGINE = TimeSeries 
SETTINGS tags_to_columns = {'instance': 'instance', 'job': 'job'}
```

该语句将把 `instance` 和 `job` 列添加到内部[标签](#tags-table)目标表中。
在这种情况下，`tags` 列将不包含 `instance` 和 `job` 这两个标签，
但 `all_tags` 列会包含它们。`all_tags` 列是临时列，其唯一用途是用于 `id` 列的 DEFAULT 表达式
中。

<div id="inner-table-engines">
  ## 内部目标表的表引擎
</div>

默认情况下，内部目标表使用以下表引擎：

* [samples](#samples-table) 表使用 [MergeTree](/zh/reference/engines/table-engines/mergetree-family/mergetree)；
* [tags](#tags-table) 表使用 [AggregatingMergeTree](/zh/reference/engines/table-engines/mergetree-family/aggregatingmergetree)，因为相同的数据通常会多次插入该表，因此需要一种去重方式，
  同时还需要对列 `min_time` 和 `max_time` 进行聚合；
* [metrics](#metrics-table) 表使用 [ReplacingMergeTree](/zh/reference/engines/table-engines/mergetree-family/replacingmergetree)，因为相同的数据通常会多次插入该表，因此需要一种去重方式。

如果指定了其他表引擎，内部目标表也可以使用它们：

```sql theme={null}
CREATE TABLE my_table ENGINE=TimeSeries
SAMPLES ENGINE=ReplicatedMergeTree
TAGS ENGINE=ReplicatedAggregatingMergeTree
METRICS ENGINE=ReplicatedReplacingMergeTree
```

<div id="external-target-tables">
  ## 外部目标表
</div>

可以让 `TimeSeries` 表使用手动创建的目标表：

```sql theme={null}
CREATE TABLE samples_for_my_table
(
    `id` UUID,
    `timestamp` DateTime64(3),
    `value` Float64
)
ENGINE = MergeTree
ORDER BY (id, timestamp);

CREATE TABLE tags_for_my_table ...

CREATE TABLE metrics_for_my_table ...

CREATE TABLE my_table ENGINE=TimeSeries SAMPLES samples_for_my_table TAGS tags_for_my_table METRICS metrics_for_my_table;
```

外部表的列类型 (`id`、`timestamp`、`value`，以及 [`tags_to_columns`](#settings) 中列出的各个 `<tag_value_column>`) 必须与 `TimeSeries` 表原本会在内部生成的类型一致 (类型约束请参见 [Samples 表](#samples-table)、[标签表](#tags-table) 和 [指标表](#metrics-table)) 。类型不匹配会在 `CREATE` 时报告。

外部标签目标的 id 生成器表达式会在 INSERT 时按以下顺序解析：先是 [`id_generator`](#settings) 设置 (如果已设置) ，然后是外部表 `id` 列上声明的 `DEFAULT` (如果有) ，最后是根据 `id` 类型派生出的规范生成器) 。因此，该设置会覆盖外部表上声明的任何 `DEFAULT`——详见 [The `id` column](#id-column)。

<div id="altering-settings">
  ## 修改设置
</div>

执行 `CREATE` 后，可更改以下两个设置：

* `id_generator`
* `filter_by_min_time_and_max_time`

```sql theme={null}
ALTER TABLE my_table MODIFY SETTING id_generator = 'sipHash64(metric_name, all_tags)';
ALTER TABLE my_table MODIFY SETTING filter_by_min_time_and_max_time = 0;
```

请注意，如果在标签表中已有数据后更改 `id_generator`，同一 metric+tag 组合可能会生成不同的 ID——旧行会保留原来的 ID，新行则会使用新的生成器。

其他设置不能通过 `ALTER ... MODIFY SETTING` 更改，因为它们在 `CREATE` 时就已经固化在内部表的 schema 中。

<div id="settings">
  ## 设置
</div>

以下列出了在定义 `TimeSeries` 表时可指定的设置：

| 名称                                   | 类型   | 默认值         | 说明                                                                                                                                                   |
| ------------------------------------ | ---- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id_generator`                       | 表达式  | 取决于 `id` 类型 | 根据时间序列的标签计算其标识符 (指纹) 的表达式。如果未设置，则使用 `id` 列的默认表达式。如果 `id` 列的默认表达式也未设置，则会自动选择该表达式                                                                      |
| `tags_to_columns`                    | Map  | {}          | 指定哪些标签应映射到 [标签](#tags-table) 表中的独立列。语法：`{'tag1': 'column1', 'tag2' : column2, ...}`                                                                  |
| `use_all_tags_column_to_generate_id` | Bool | true        | 在生成用于计算时间序列标识符的表达式时，此标志会启用在计算中使用 `all_tags` 列                                                                                                        |
| `store_min_time_and_max_time`        | Bool | true        | 如果设置为 true，则该表会为每个时间序列存储 `min_time` 和 `max_time`                                                                                                     |
| `aggregate_min_time_and_max_time`    | Bool | true        | 创建内部目标 `tags` 表时，此标志会启用将 `min_time` 列的类型设为 `SimpleAggregateFunction(min, Nullable(DateTime64(3)))`，而不是仅使用 `Nullable(DateTime64(3))`；`max_time` 列同样如此 |
| `filter_by_min_time_and_max_time`    | Bool | true        | 如果设置为 true，则该表会使用 `min_time` 和 `max_time` 列来过滤时间序列                                                                                                   |

<div id="functions">
  # 函数
</div>

以下列出了支持将 `TimeSeries` 表作为参数的函数：

* [timeSeriesSamples](/zh/reference/functions/table-functions/timeSeriesSamples)
* [timeSeriesTags](/zh/reference/functions/table-functions/timeSeriesTags)
* [timeSeriesMetrics](/zh/reference/functions/table-functions/timeSeriesMetrics)
