Un motor de tabla que almacena series temporales, es decir, un conjunto de valores asociados a marcas de tiempo y tags (o labels):
metric_name1[tag1=value1, tag2=value2, ...] = {timestamp1: value1, timestamp2: value2, ...}
metric_name2[...] = ...
Esta es una funcionalidad experimental que puede cambiar de formas incompatibles con versiones anteriores en futuras versiones.
Habilite el uso del motor de tabla TimeSeries
con el ajuste allow_experimental_time_series_table.
Ejecute el comando set allow_experimental_time_series_table = 1.
CREATE TABLE name [(columns)] ENGINE=TimeSeries
[SETTINGS var1=value1, ...]
[DATA db.data_table_name | DATA ENGINE data_table_engine(arguments)]
[TAGS db.tags_table_name | TAGS ENGINE tags_table_engine(arguments)]
[METRICS db.metrics_table_name | METRICS ENGINE metrics_table_engine(arguments)]
Es más fácil empezar con la configuración predeterminada (se puede crear una tabla TimeSeries sin especificar una lista de columnas):
CREATE TABLE my_table ENGINE=TimeSeries
A continuación, esta tabla puede utilizarse con los siguientes protocolos (debe asignarse un puerto en la configuración del servidor):
Una tabla TimeSeries no tiene datos propios; todo se almacena en sus tablas de destino.
Esto es similar al funcionamiento de una vista materializada,
con la diferencia de que una vista materializada tiene una sola tabla de destino,
mientras que una tabla TimeSeries tiene tres tablas de destino llamadas data, tag y metrics.
Las tablas de destino pueden especificarse explícitamente en la consulta CREATE TABLE
o el motor de tabla TimeSeries puede generar automáticamente tablas de destino internas.
Las tablas de destino son las siguientes:
La tabla data contiene series temporales asociadas a algún identificador.
La tabla data debe tener las siguientes columnas:
| Nombre | ¿Obligatorio? | Tipo predeterminado | Tipos posibles | Descripción |
|---|
id | [x] | UUID | cualquiera | Identifica una combinación de nombres de métricas y etiquetas |
timestamp | [x] | DateTime64(3) | DateTime64(X) | Un instante temporal |
value | [x] | Float64 | Float32 o Float64 | Un valor asociado al timestamp |
La tabla tags contiene identificadores calculados para cada combinación de un nombre de métrica y etiquetas.
La tabla tags debe tener las siguientes columnas:
| Nombre | ¿Obligatorio? | Tipo predeterminado | Tipos posibles | Descripción |
|---|
id | [x] | UUID | cualquiera (debe coincidir con el tipo de id de la tabla data) | Un id identifica una combinación de un nombre de métrica y etiquetas. La expresión DEFAULT especifica cómo calcular ese identificador |
metric_name | [x] | LowCardinality(String) | String o LowCardinality(String) | El nombre de una métrica |
<tag_value_column> | [ ] | String | String o LowCardinality(String) o LowCardinality(Nullable(String)) | El valor de una etiqueta específica; el nombre de la etiqueta y el nombre de la columna correspondiente se especifican en la configuración tags_to_columns |
tags | [x] | Map(LowCardinality(String), String) | Map(String, String) o Map(LowCardinality(String), String) o Map(LowCardinality(String), LowCardinality(String)) | Mapa de etiquetas que excluye la etiqueta __name__, que contiene el nombre de una métrica, y las etiquetas cuyos nombres se enumeran en la configuración tags_to_columns |
all_tags | [ ] | Map(String, String) | Map(String, String) o Map(LowCardinality(String), String) o Map(LowCardinality(String), LowCardinality(String)) | Columna efímera; cada fila es un mapa de todas las etiquetas, excluyendo únicamente la etiqueta __name__, que contiene el nombre de una métrica. El único propósito de esta columna es usarse al calcular id |
min_time | [ ] | Nullable(DateTime64(3)) | DateTime64(X) o Nullable(DateTime64(X)) | Marca temporal mínima de la serie temporal con ese id. La columna se crea si store_min_time_and_max_time es true |
max_time | [ ] | Nullable(DateTime64(3)) | DateTime64(X) o Nullable(DateTime64(X)) | Marca temporal máxima de la serie temporal con ese id. La columna se crea si store_min_time_and_max_time es true |
La tabla metrics contiene información sobre las métricas recopiladas, sus tipos y sus descripciones.
La tabla metrics debe tener las siguientes columnas:
| Nombre | ¿Obligatorio? | Tipo predeterminado | Tipos posibles | Descripción |
|---|
metric_family_name | [x] | String | String o LowCardinality(String) | El nombre de una familia de métricas |
type | [x] | String | String o LowCardinality(String) | El tipo de una familia de métricas; uno de “counter”, “gauge”, “summary”, “stateset”, “histogram”, “gaugehistogram” |
unit | [x] | String | String o LowCardinality(String) | La unidad utilizada en una métrica |
help | [x] | String | String o LowCardinality(String) | La descripción de una métrica |
Cualquier fila insertada en una tabla TimeSeries se almacenará realmente en esas tres tablas de destino.
Una tabla TimeSeries contiene todas esas columnas de las tablas data, etiquetas y métricas.
Hay varias formas de crear una tabla con el motor de tabla TimeSeries.
La sentencia más sencilla
CREATE TABLE my_table ENGINE=TimeSeries
en realidad creará la siguiente tabla (puedes comprobarlo ejecutando SHOW CREATE TABLE my_table):
CREATE TABLE my_table
(
`id` UUID DEFAULT reinterpretAsUUID(sipHash128(metric_name, all_tags)),
`timestamp` DateTime64(3),
`value` Float64,
`metric_name` LowCardinality(String),
`tags` Map(LowCardinality(String), String),
`all_tags` Map(String, String),
`min_time` Nullable(DateTime64(3)),
`max_time` Nullable(DateTime64(3)),
`metric_family_name` String,
`type` String,
`unit` String,
`help` String
)
ENGINE = TimeSeries
DATA ENGINE = MergeTree ORDER BY (id, timestamp)
DATA INNER UUID '01234567-89ab-cdef-0123-456789abcdef'
TAGS ENGINE = AggregatingMergeTree PRIMARY KEY metric_name ORDER BY (metric_name, id)
TAGS INNER UUID '01234567-89ab-cdef-0123-456789abcdef'
METRICS ENGINE = ReplacingMergeTree ORDER BY metric_family_name
METRICS INNER UUID '01234567-89ab-cdef-0123-456789abcdef'
Así que las columnas se generaron automáticamente y, además, hay tres UUID internos en esta sentencia:
uno por cada tabla de destino interna que se creó.
(Normalmente, los UUID internos no se muestran a menos que se habilite la opción
show_table_uuid_in_table_create_query_if_not_nil
.)
Las tablas de destino internas tienen nombres como .inner_id.data.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,
.inner_id.tags.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, .inner_id.metrics.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
y cada tabla de destino tiene columnas que son un subconjunto de las columnas de la tabla principal TimeSeries:
CREATE TABLE default.`.inner_id.data.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
(
`id` UUID,
`timestamp` DateTime64(3),
`value` Float64
)
ENGINE = MergeTree
ORDER BY (id, timestamp)
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)
CREATE TABLE default.`.inner_id.metrics.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
(
`metric_family_name` String,
`type` String,
`unit` String,
`help` String
)
ENGINE = ReplacingMergeTree
ORDER BY metric_family_name
Ajuste de los tipos de las columnas
Puede ajustar los tipos de casi cualquier columna de las tablas de destino internas especificándolos explícitamente
al definir la tabla principal. Por ejemplo,
CREATE TABLE my_table
(
timestamp DateTime64(6)
) ENGINE=TimeSeries
hará que la tabla data interna almacene la marca de tiempo en microsegundos en lugar de en milisegundos:
CREATE TABLE default.`.inner_id.data.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
(
`id` UUID,
`timestamp` DateTime64(6),
`value` Float64
)
ENGINE = MergeTree
ORDER BY (id, timestamp)
La columna id contiene identificadores; cada identificador se calcula a partir de una combinación de un nombre de métrica y etiquetas.
La expresión DEFAULT de la columna id es la que se utilizará para calcular dichos identificadores.
Tanto el tipo de la columna id como esa expresión pueden ajustarse especificándolos explícitamente:
CREATE TABLE my_table
(
id UInt64 DEFAULT sipHash64(metric_name, all_tags)
)
ENGINE=TimeSeries
Hay dos columnas que contienen mapas de tag: tags y all_tags. En este ejemplo significan lo mismo; sin embargo, pueden ser diferentes
si se usa la configuración tags_to_columns. Esta configuración permite especificar que un tag concreto debe almacenarse en una columna independiente en lugar de almacenarse
en un mapa dentro de la columna tags:
CREATE TABLE my_table
ENGINE = TimeSeries
SETTINGS tags_to_columns = {'instance': 'instance', 'job': 'job'}
Esta sentencia añadirá las siguientes columnas:
`instance` String,
`job` String
a la definición tanto de my_table como de su tag interna. En este caso, la columna tags no contendrá los tag instance y job,
pero la columna all_tags sí las contendrá. La columna all_tags es efímera y su único propósito es servir para la expresión DEFAULT
de la columna id.
Los tipos de las columnas pueden ajustarse especificándolos de forma explícita:
CREATE TABLE my_table (
instance LowCardinality(String),
job LowCardinality(Nullable(String))
)
ENGINE=TimeSeries
SETTINGS tags_to_columns = {'instance': 'instance', 'job': 'job'}
Motores de las tablas internas de destino
De forma predeterminada, las tablas internas de destino usan los siguientes motores de tabla:
- la tabla data usa MergeTree;
- la tabla tags usa AggregatingMergeTree porque los mismos datos suelen insertarse varias veces en esta tabla, por lo que hace falta una forma
de eliminar duplicados, y también porque es necesario realizar agregación para las columnas
min_time y max_time;
- la tabla metrics usa ReplacingMergeTree porque los mismos datos suelen insertarse varias veces en esta tabla, por lo que hace falta una forma
de eliminar duplicados.
También se pueden usar otros motores de tabla para las tablas internas de destino si así se especifica:
CREATE TABLE my_table ENGINE=TimeSeries
DATA ENGINE=ReplicatedMergeTree
TAGS ENGINE=ReplicatedAggregatingMergeTree
METRICS ENGINE=ReplicatedReplacingMergeTree
Tablas de destino externas
Es posible hacer que una tabla TimeSeries utilice una tabla creada manualmente:
CREATE TABLE data_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 DATA data_for_my_table TAGS tags_for_my_table METRICS metrics_for_my_table;
Aquí tienes una lista de configuraciones que se pueden especificar al definir una tabla TimeSeries:
| Nombre | Tipo | Predeterminado | Descripción |
|---|
tags_to_columns | Map | Map que especifica qué etiquetas deben colocarse en columnas independientes en la tabla tags. Sintaxis: {'tag1': 'column1', 'tag2' : column2, ...} | |
use_all_tags_column_to_generate_id | Bool | true | Al generar una expresión para calcular el identificador de una serie temporal, esta opción permite usar la columna all_tags en ese cálculo |
store_min_time_and_max_time | Bool | true | Si se establece en true, la tabla almacenará min_time y max_time para cada serie temporal |
aggregate_min_time_and_max_time | Bool | true | Al crear una tabla tags interna de destino, esta opción permite usar SimpleAggregateFunction(min, Nullable(DateTime64(3))) en lugar de solo Nullable(DateTime64(3)) como tipo de la columna min_time, y lo mismo para la columna max_time |
filter_by_min_time_and_max_time | Bool | true | Si se establece en true, la tabla usará las columnas min_time y max_time para filtrar las series temporales |
Aquí tienes una lista de funciones que admiten una tabla TimeSeries como argumento:
Última modificación el 10 de junio de 2026