Skip to main content
Un motor de tabla que almacena series temporales, es decir, un conjunto de valores asociados a marcas de tiempo y etiquetas (o labels):
Esta es una funcionalidad de vista previa privada que puede cambiar de formas incompatibles con versiones anteriores en futuras versiones. Habilite el uso del motor de tabla TimeSeries con el SETTING enable_time_series_table. Ejecute el comando set enable_time_series_table = 1.
El motor de tabla TimeSeries está disponible en ClickHouse Cloud como funcionalidad de vista previa privada. Los servicios que participan en la vista previa privada ya tienen configurado el SETTING enable_time_series_table. Los demás servicios de ClickHouse Cloud no cuentan con esta configuración, y no es posible habilitar el motor por su cuenta en dichos servicios.

Sintaxis

La palabra clave SAMPLES tiene el alias DATA, y la palabra clave METRIC FAMILIES tiene el alias METRICS; ambos se mantienen por compatibilidad con versiones anteriores. La definición de una tabla de una version anterior a 4 se escribe con METRICS, de modo que un servidor más antiguo pueda leerla.

Uso

Es más fácil empezar con la configuración predeterminada (se puede crear una tabla TimeSeries sin especificar una lista de columnas):
A continuación, esta tabla puede utilizarse con los siguientes protocolos (debe asignarse un puerto en la configuración del servidor):

Columnas externas

Las columnas de una tabla TimeSeries se generan automáticamente. Son columnas externas: no almacenan datos, solo proporcionan la interfaz para SELECT/INSERT. Los datos reales se almacenan en las tablas de destino. Aquí está la lista de las columnas externas: Ejemplo:
Se permite que metric_name esté vacío durante la inserción, lo que significa que el nombre de la métrica se especifica en tags con __name__, por ejemplo:
Para insertar metadatos de métricas, insértelos en las columnas metric_family, type, unit y help:

Especificación de columnas externas

La columna externa samples se puede incluir explícitamente en una sentencia CREATE TABLE para sobrescribir su tipo predeterminado Array(Tuple(DateTime64(3), Float64)) (también se acepta su nombre anterior time_series). ClickHouse extrae de la tupla los tipos de marca de tiempo y escalares, y los propaga a la tabla interna de muestras:
Esto equivale a declarar directamente los tipos de las columnas timestamp y value en la cláusula INNER COLUMNS de samples:
Si ambas formas se usan en la misma sentencia CREATE TABLE, los tipos declarados deben coincidir.

Tablas de destino

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 obligatorias llamadas samples, etiqueta y familia de métricas, y una tabla de destino opcional muestra reciente que está habilitada de forma predeterminada (consulte la configuración recent_samples_ttl_seconds). 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 filas insertadas en una tabla TimeSeries se transforman, se dividen en bloques y se insertan en estas tablas de destino. Las tablas de destino son las siguientes:

Tabla samples

La tabla samples contiene series temporales asociadas a algún identificador. La tabla samples debe tener las siguientes columnas: Las columnas que crea el propio motor utilizan códecs de compresión para series temporales: timestamp CODEC(Delta, T64, ZSTD(3)) y value CODEC(ALP, ZSTD(3)). Las marcas de tiempo casi monotónicas apenas se comprimen con códecs genéricos y, de lo contrario, pueden representar la mayor parte del tamaño en disco de la tabla samples. El motor habilita ALP para sus tablas internas de samples y muestras recientes sin requerir que se establezca enable_alp_codec. Consulte también Ajustar los tipos de las columnas.

Tabla de muestras recientes

La tabla de muestras recientes es opcional y está habilitada de forma predeterminada (véase el ajuste recent_samples_ttl_seconds; si se establece en cero, la tabla se deshabilita). Contiene una copia de las muestras más recientes que el TTL definido por ese ajuste, y debe tener las mismas columnas que la tabla samples. La columna generada timestamp usa CODEC(Delta, T64, ZSTD(3)), y la columna generada value usa CODEC(ALP, ZSTD(3)). Cada muestra insertada se escribe tanto en la tabla de muestras como en la tabla de muestras recientes. Las consultas cuyo rango temporal se ajusta a la ventana del TTL leen de la tabla de muestras recientes en lugar de la tabla principal de muestras, ya que es mucho más pequeña (esto se puede deshabilitar con el ajuste a nivel de consulta time_series_prefer_recent_samples_table). El TTL de la tabla interna de muestras recientes siempre se deriva del ajuste recent_samples_ttl_seconds.

Tabla de etiquetas

La tabla etiquetas contiene identificadores calculados para cada combinación de un nombre de métrica y etiquetas. La tabla etiquetas debe tener las siguientes columnas: Las nuevas tablas internas de etiquetas de la versión 5 y posteriores con un motor de la familia MergeTree tienen un índice de texto invertido sobre tags: INDEX tags_idx tags TYPE text(tokenizer = 'keyValuePairs'). Acelera las coincidencias exactas de etiquetas como {job="api"} en PromQL al buscar conjuntamente la clave y el valor. Las comparaciones con una cadena vacía también coinciden con etiquetas ausentes y no utilizan este índice. Los índices explícitos declarados en TAGS INNER COLUMNS sustituyen al índice predeterminado. Las tablas existentes y las tablas de etiquetas externas conservan sus índices; añade y materializa el índice en su tabla de destino de etiquetas para habilitarlo.

Tabla de familias de métricas

La tabla familias de métricas contiene información sobre las familias de métricas recopiladas, sus tipos y sus descripciones. Una familia de métricas es un grupo de métricas con el mismo nombre (el tag __name__) y el mismo tipo; por ejemplo, un histogram es una familia de métricas que consta de múltiples métricas. La tabla familias de métricas debe tener las siguientes columnas:

Creación

Existen varias formas de crear una table con el motor de tabla TimeSeries. La sentencia más sencilla
en realidad creará la siguiente tabla (puedes comprobarlo ejecutando SHOW CREATE TABLE my_table):
Es decir, las columnas se generaron automáticamente y además hay cuatro tablas internas de destino con sus propias definiciones de columnas almacenadas en las cláusulas INNER COLUMNS. La opción recent_samples_ttl_seconds se escribió en la cláusula SETTINGS con su valor predeterminado: la opción define el TTL de la tabla de muestras recientes, por lo que su valor efectivo queda fijado al crearla. Además, la versión más reciente del esquema quedó fijada en la opción version (véase Control de versiones del esquema). Las tablas internas de destino tienen nombres como .inner_id.samples.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, .inner_id.recentsamples.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, .inner_id.tags.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, .inner_id.metricfamilies.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx y cada tabla de destino tiene su propio conjunto de columnas:

Creación de una tabla AS a partir de una tabla existente

La sentencia CREATE TABLE new_table AS existing_table crea una tabla TimeSeries configurada como existing_table, que debe ser una tabla TimeSeries. Los destinos externos de existing_table no se copian: la propia sentencia debe declarar esos destinos. La sentencia copia de existing_table:
  • la cláusula SETTINGS, excepto version: la nueva tabla siempre obtiene la versión más reciente. Los ajustes especificados en la propia sentencia se combinan por nombre con los copiados, por lo que prevalece un ajuste especificado y name = DEFAULT restablece un ajuste copiado a su valor predeterminado;
  • las cláusulas INNER COLUMNS e INNER ENGINE de cada tabla interna. Se conservan las columnas personalizadas (p. ej., columnas adicionales o columnas con un códec o una expresión DEFAULT) y las partes personalizadas del motor (p. ej., un motor con argumentos, una clave de ordenación personalizada o un ajuste del motor); las demás columnas y partes del motor se ajustan a los ajustes de la nueva tabla, de modo que p. ej., tags_to_columns, aggregate_min_time_and_max_time o tags_index_granularity especificadas en la sentencia surtan efecto.
Los tipos de las columnas id, de marca de tiempo y de valor, así como el tipo de replicación de los motores internos (MergeTree, ReplicatedMergeTree o SharedMergeTree), también se toman de existing_table, a menos que la propia sentencia los declare. La lista de columnas externas se vuelve a generar y no se copia. Una tabla creada con una versión anterior de ClickHouse puede utilizarse como existing_table: la nueva tabla obtiene la estructura actual, p. ej., el tipo actual de id y la expresión de identificador predeterminada.

Ajuste de los tipos de las columnas

Puede ajustar los tipos de las columnas en las tablas internas de destino mediante la cláusula INNER COLUMNS. Por ejemplo, para almacenar marcas de tiempo en microsegundos y valores como Float32, use:
Especificar columnas internas sin códecs implica usar el códec predeterminado para ellas:

La columna id

La columna id contiene identificadores; cada uno se calcula a partir de una combinación de un nombre de métrica y etiquetas. El tipo y la expresión DEFAULT utilizados para generar los identificadores se pueden personalizar mediante la cláusula TAGS INNER COLUMNS:
La columna id puede ser de cualquier tipo comparable que no sea Nullable. Los tipos de id declarados en las tablas internas de samples y etiquetas deben coincidir. Si no se proporciona ninguna expresión DEFAULT para la columna id y la configuración id_generator no está definida, ClickHouse elegirá automáticamente la expresión DEFAULT en función del tipo de id, pero solo si el tipo de id es uno de UUID, UInt64, UInt128, FixedString(16), esos mismos tipos envueltos en LowCardinality, o una tupla de dos de esos tipos. Para dicha tupla, la expresión elegida automáticamente calcula un hash del nombre de la métrica en el primer componente y un hash de todas las etiquetas en el segundo componente. Un tipo de identificador LowCardinality, por ejemplo Tuple(UInt64, LowCardinality(UUID)), mantiene los identificadores codificados mediante diccionario: la tabla de samples almacena pequeños diccionarios por bloque con índices de diccionario en lugar de repetir el identificador completo en cada fila, lo que reduce la cantidad de datos leídos por las consultas. La configuración id_generator permite la misma personalización sin usar la cláusula INNER COLUMNS:
Si el ajuste está definido, se usa para generar id incluso si el DEFAULT de la columna contiene otra expresión. El tipo de la columna id también se puede especificar en la configuración id_type en lugar de en la cláusula INNER COLUMNS:
Cuando la configuración id_generator está definida, la configuración id_type se registra automáticamente en el momento del CREATE, de modo que la definición conserva el tipo para el que se escribió la expresión.

La columna tags

La columna tags contiene todas las etiquetas de una serie temporal, incluida la etiqueta __name__ con el nombre de una métrica. La configuración tags_to_columns permite especificar que una etiqueta concreta también debe almacenarse en una columna independiente además del mapa dentro de la columna tags:
Esta sentencia añadirá las columnas instance y job a la tabla de destino interna etiquetas. Los valores de las etiquetas instance y job se almacenarán tanto en esas columnas como en la columna tags.
En las tablas creadas con versiones anteriores de ClickHouse, la columna tags contiene solo las etiquetas, sin columnas específicas ni el nombre de la métrica, y la columna all_tags es una columna efímera que se rellenaba durante la inserción con todas las etiquetas excepto el nombre de la métrica.

Motores de las tablas internas de destino

De forma predeterminada, las tablas internas de destino usan los siguientes motores de tabla: La familia de motores de las tablas internas generadas sigue la configuración a nivel de consulta default_table_engine: con default_table_engine = ReplicatedMergeTree o SharedMergeTree, las tablas internas usan los motores Replicated o Shared correspondientes. Con default_table_engine = None (o cualquier otro valor), los motores de las tablas internas deben especificarse explícitamente. Todas las tablas internas deben tener el mismo tipo de replicación: si una de ellas está replicada (o compartida), las demás tablas internas también deben estar replicadas (o compartidas); de lo contrario, su contenido divergiría entre réplicas. Por ejemplo, declarar SAMPLES INNER ENGINE = ReplicatedMergeTree(...) requiere que los demás motores internos también estén replicados, ya sea declarados explícitamente o generados con default_table_engine = ReplicatedMergeTree. También se pueden usar otros motores de tabla para las tablas internas de destino si así se especifica:
La tabla etiquetas mantiene las columnas de etiquetas (y el Map tags) fuera de su clave de ordenación, algo que AggregatingMergeTree rechaza de forma predeterminada (consulte allow_dimensions_outside_sorting_key). Esto es seguro aquí porque esas columnas dependen funcionalmente de id, que forma parte de la clave de ordenación, por lo que todas las filas que un merge en segundo plano colapsa comparten los mismos valores. Cuando la tabla interna de etiquetas se genera o su motor se especifica en línea como arriba, TimeSeries establece automáticamente allow_dimensions_outside_sorting_key = 1 en ella; para una tabla de etiquetas de agregación externa creada manualmente, debe configurarlo usted mismo.

Tablas de destino externas

Es posible hacer que una tabla TimeSeries utilice una tabla creada manualmente:
También se puede utilizar una tabla externa como destino de muestra reciente (la cláusula RECENT SAMPLES my_recent_samples_table). Dicha tabla debe tener las mismas columnas que una tabla externa de samples y debe conservar al menos recent_samples_ttl_seconds segundos de datos, lo cual es responsabilidad del usuario. Los tipos de columna de las tablas externas (id, timestamp, value y las <tag_value_column> enumeradas en tags_to_columns) deben coincidir con los que la tabla TimeSeries generaría internamente en otras circunstancias (consulte tabla Samples, tabla Etiquetas y tabla Familias de métricas para conocer las restricciones de tipo). Las discrepancias de tipo se notifican en el momento de CREATE. El tipo de la columna id de una tabla externa de etiquetas y la expresión que genera los identificadores se registran en las configuraciones id_type e id_generator en el momento de CREATE (a partir de la version 2), de modo que la definición de la tabla TimeSeries los conserva: por ejemplo, CREATE TABLE ... AS my_table lee el tipo de id de la definición de my_table sin leer sus tablas de destino externas. Si no se especifica la configuración id_generator, se establece con el DEFAULT declarado en la columna id de la tabla externa (si existe) y, en caso contrario, con el generador canónico derivado del tipo de id. La expresión registrada se utiliza para generar id incluso si el DEFAULT de la tabla externa cambia posteriormente; consulte La columna id para obtener más detalles.

Modificar los ajustes

Se pueden modificar dos ajustes después de CREATE:
  • id_generator
  • filter_by_min_time_and_max_time
Ten en cuenta que cambiar id_generator cuando ya hay datos en la tabla de etiquetas puede generar IDs distintos para la misma combinación de métrica+etiqueta: las filas antiguas conservan sus IDs anteriores y las nuevas usan el nuevo generador. Los demás ajustes no se pueden cambiar con ALTER ... MODIFY SETTING: la mayoría quedan incorporados en el esquema de las tablas internas en el momento de CREATE, y el ajuste version se fija automáticamente en el momento de CREATE e identifica el propio esquema (consulta Control de versiones del esquema).

Configuración

Aquí tienes una lista de configuraciones que se pueden especificar al definir una tabla TimeSeries:

Control de versiones del esquema

El motor de tabla TimeSeries y la capa de ejecución de PromQL están en desarrollo activo: el conjunto de tablas de destino y su estructura pueden cambiar entre versiones de ClickHouse. Para que dichos cambios sean detectables, cada tabla TimeSeries almacena su versión en el SETTING version. La versión se fija automáticamente en la consulta CREATE al crear la tabla —su valor es la última versión conocida por el servidor (actualmente 5)—, persiste en los metadatos de la tabla y no puede modificarse mediante ALTER. Las tablas creadas antes de que se introdujera el SETTING se consideran de versión 0. Lo normal es omitir el SETTING en la consulta CREATE TABLE: así la tabla obtiene la última versión. Se acepta un valor explícito de version siempre que el servidor admita esa versión; en ese caso la tabla se define tal como lo hace esa versión (consulte Historial de versiones). CREATE TABLE ... AS other_table no copia la versión de la otra tabla; consulte Crear una tabla AS una tabla existente. Un servidor admite un rango de versiones, y la versión mínima puede variar según se trate de lectura con SELECT, de escritura con INSERT o con el protocolo remote-write de Prometheus, o de evaluación de PromQL (las funciones de tabla prometheusQuery, prometheusQueryRange y timeSeriesSelector, el dialecto promql y la API HTTP de consultas de Prometheus):
  • Si la versión de una tabla TimeSeries es demasiado antigua para PromQL, se rechazan las consultas PromQL sobre ella. La excepción sugiere volver a crear la tabla: cree una nueva tabla TimeSeries, copie los datos con una consulta INSERT ... SELECT y sustituya la tabla antigua por la nueva.
  • Si la versión es demasiado antigua para escribir en ella, se rechazan las consultas INSERT y el protocolo remote-write de Prometheus, mientras que las consultas SELECT siguen funcionando.
  • Si la versión es demasiado antigua para el servidor en general, se rechaza cualquier consulta sobre la tabla (excepto SHOW CREATE TABLE, DETACH y DROP).

Historial de versiones

Funciones

Aquí tienes una lista de funciones que admiten una tabla TimeSeries como argumento:
Última modificación el 26 de septiembre de 2026