将 CH 用作时间序列数据库的方法不止一种。我个人的偏好是使用一个字符串数组作为指标名称,使用一个 Float64 数组作为指标值。
这是一个示例时间序列表:
CREATE TABLE ts1(
entity String,
ts UInt64, -- timestamp, milliseconds from January 1 1970
m Array(String), -- names of the metrics
v Array(Float32), -- values of the metrics
d Date MATERIALIZED toDate(round(ts/1000)), -- auto generate date from ts column
dt DateTime MATERIALIZED toDateTime(round(ts/1000)) -- auto generate date time from ts column
) ENGINE = MergeTree(d, entity, 8192)
在这里,我们为实体(cpu)加载两个指标(负载、温度):
INSERT INTO ts1(entity, ts, m, v)
VALUES ('cpu', 1509232010254, ['load','temp'], [0.85, 68])
并查询 CPU 负载:
SELECT
entity,
dt,
ts,
v[indexOf(m, 'load')] AS load
FROM ts1
WHERE entity = 'cpu'
┌─entity─┬──────────────────dt─┬────────────ts─┬─load─┐
│ cpu │ 2017-10-28 23:06:50 │ 1509232010254 │ 0.85 │
└────────┴─────────────────────┴───────────────┴──────┘
以元组数组的形式获取数据:
SELECT
entity,
dt,
ts,
arrayMap((mm, vv) -> (mm, vv), m, v) AS metrics
FROM ts1
┌─entity─┬──────────────────dt─┬────────────ts─┬─metrics─────────────────────┐
│ cpu │ 2017-10-28 23:06:50 │ 1509232010254 │ [('load',0.85),('temp',68)] │
└────────┴─────────────────────┴───────────────┴─────────────────────────────┘
以元组行的形式获取数据:
SELECT
entity,
dt,
ts,
arrayJoin(arrayMap((mm, vv) -> (mm, vv), m, v)) AS metric
FROM ts1
┌─entity─┬──────────────────dt─┬────────────ts─┬─metric────────┐
│ cpu │ 2017-10-28 23:06:50 │ 1509232010254 │ ('load',0.85) │
│ cpu │ 2017-10-28 23:06:50 │ 1509232010254 │ ('temp',68) │
└────────┴─────────────────────┴───────────────┴───────────────┘
获取具有所需指标的行:
SELECT
entity,
dt,
ts,
arrayJoin(arrayMap((mm, vv) -> (mm, vv), m, v)) AS metrics
FROM ts1
WHERE metrics.1 = 'load'
┌─entity─┬──────────────────dt─┬────────────ts─┬─metrics───────┐
│ cpu │ 2017-10-28 23:06:50 │ 1509232010254 │ ('load',0.85) │
└────────┴─────────────────────┴───────────────┴───────────────┘
获取指标名称和值作为列:
SELECT
entity,
dt,
ts,
arrayJoin(arrayMap((mm, vv) -> (mm, vv), m, v)) AS metric,
metric.1 AS metric_name,
metric.2 AS metric_value
FROM ts1
┌─entity─┬──────────────────dt─┬────────────ts─┬─metric────────┬─metric_name─┬─metric_value─┐
│ cpu │ 2017-10-28 23:06:50 │ 1509232010254 │ ('load',0.85) │ load │ 0.85 │
│ cpu │ 2017-10-28 23:06:50 │ 1509232010254 │ ('temp',68) │ temp │ 68 │
└────────┴─────────────────────┴───────────────┴───────────────┴─────────────┴──────────────┘
由于 CH 有很多有用的日期和时间函数,以及高阶函数和元组,我认为它几乎是一个自然的时间序列数据库。