This is an experimental feature that may change in backwards-incompatible ways in the future releases.
Enable usage of the TimeSeries table engine
with allow_experimental_time_series_table setting.
Input the command
set allow_experimental_time_series_table = 1.Syntax
The keyword
SAMPLES has an alias DATA which is kept for backwards compatibility.Usage
It’s easier to start with everything set by default (it’s allowed to create aTimeSeries table without specifying a list of columns):
Outer columns
Columns of a TimeSeries table are generated automatically. These are outer columns, they store no data, they just provide interface for SELECT/INSERT. Actual data is stored in target tables. Here is the list of the outer columns:
Example:
metric_name is allowed to be empty on insertion, that means the metric name is specified in tags under __name__, for example:
metric_family, type, unit, and help columns:
Specifying outer columns
The outertime_series column can be listed explicitly in a CREATE TABLE statement to override its default Array(Tuple(DateTime64(3), Float64)) type. ClickHouse extracts the timestamp and scalar types from the tuple and propagates them to the inner samples table:
INNER COLUMNS clause directly:
CREATE TABLE statement, the declared types must match.
Target tables
ATimeSeries table doesn’t have its own data, everything is stored in its target tables.
This is similar to how a materialized view works,
with the difference that a materialized view has one target table
whereas a TimeSeries table has three target tables named samples, tags, and metrics.
The target tables can be either specified explicitly in the CREATE TABLE query
or the TimeSeries table engine can generate inner target tables automatically.
Rows inserted into a TimeSeries table are transformed, split into blocks, and inserted in these three target tables.
The target tables are the following:
Samples table
The samples table contains time series associated with some identifier. The samples table must have columns:Tags table
The tags table contains identifiers calculated for each combination of a metric name and tags. The tags table must have columns:Metrics table
The metrics table contains some information about metrics been collected, the types of those metrics and their descriptions. The metrics table must have columns:Creation
There are multiple ways to create a table with theTimeSeries table engine.
The simplest statement
SHOW CREATE TABLE my_table):
INNER COLUMNS clauses.
Inner target tables have names like .inner_id.samples.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,
.inner_id.tags.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, .inner_id.metrics.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
and each target table has its own set of columns:
Creating a table AS existing table
StatementCREATE TABLE new_table AS existing_table copies from the existing_table:
SETTINGSINNER COLUMNSfor each kindINNER ENGINEfor each kind
existing_table has external targets.
The outer column list is regenerated and not copied.
Adjusting types of columns
You can adjust the types of columns in the inner target tables using theINNER COLUMNS clause. For example, to store timestamps in microseconds and values as Float32:
The id column
The id column contains identifiers, every identifier is calculated for a combination of a metric name and tags.
The type and the DEFAULT expression used to generate identifiers can be customized via the TAGS INNER COLUMNS clause:
id column type must be one of UUID, UInt64, UInt128, or FixedString(16). If no DEFAULT expression is given, ClickHouse will choose it automatically based on the id type. The id types declared in the samples and tags inner tables must match.
The id_generator setting offers the same customization without using the INNER COLUMNS clause:
id even if the column’s DEFAULT contains a different expression.
The tags and all_tags columns
There are two columns containing maps of tags - tags and all_tags. In this example they mean the same, however they can be different
if setting tags_to_columns is used. This setting allows to specify that a specific tag should be stored in a separate column instead of storing
in a map inside the tags column:
instance and job to the inner tags target table.
In this case the tags column will not contain tags instance and job,
but the all_tags column will contain them. The all_tags column is ephemeral and its only purpose to be used in the DEFAULT expression
for the id column.
Table engines of inner target tables
By default inner target tables use the following table engines:- the samples table uses MergeTree;
- the tags table uses AggregatingMergeTree because the same data is often inserted multiple times to this table so we need a way
to remove duplicates, and also because it’s required to do aggregation for columns
min_timeandmax_time; - the metrics table uses ReplacingMergeTree because the same data is often inserted multiple times to this table so we need a way to remove duplicates.
External target tables
It’s possible to make aTimeSeries table use a manually created table:
id, timestamp, value, and the <tag_value_column>s listed in tags_to_columns) must match what the TimeSeries table would otherwise generate internally (see Samples table, Tags table, and Metrics table for the type constraints). Type mismatches are reported at CREATE time.
The id-generator expression for an external tags target is resolved at INSERT time in the following order: the id_generator setting (if set), then the DEFAULT declared on the external table’s id column (if any), then the canonical generator derived from the id type. The setting therefore overrides whatever DEFAULT is declared on the external table — see The id column for details.
Altering settings
Two settings can be changed afterCREATE:
id_generatorfilter_by_min_time_and_max_time
id_generator while data is already in the tags table can produce different IDs for the same metric+tag combination — old rows keep their old IDs, new rows use the new generator.
The other settings can’t be changed with ALTER ... MODIFY SETTING because they are baked into the schema of the inner tables at CREATE time.
Settings
Here is a list of settings which can be specified while defining aTimeSeries table:
Functions
Here is a list of functions supporting aTimeSeries table as an argument: