Logo Craft Homelab Docs Контакты Telegram
Трендовые github проекты в нашем телеграм канале. Подпишись →
21 февраля 2026 г.

Timeseries БД: TimescaleDB, InfluxDB

Для хранения метрик, IoT-данных и временных рядов лучше всего подходят TimescaleDB (расширение PostgreSQL) или InfluxDB. TimescaleDB — если уже используете PostgreSQL, хотите обычный SQL и нужна интеграция с реляционными данными. InfluxDB — если нужна максимальная производительность на чистых time series данных.

Метрики сервера, показания IoT-датчиков, события трекинга пользователей, биржевые котировки — всё это временные ряды. Стандартные реляционные базы данных плохо справляются с такими данными при больших объёмах: вставка миллионов строк в секунду, запросы агрегаций за месяц, автоматическое удаление устаревших данных — всё это болевые точки PostgreSQL без специализации.

Key Takeaways

  • TimescaleDB = PostgreSQL + гипертаблицы: данные разбиваются на чанки по времени, обычный SQL продолжает работать
  • time_bucket в TimescaleDB — аналог DATE_TRUNC, но с произвольными интервалами и лучшей производительностью
  • Сжатие TimescaleDB снижает объём числовых данных в 10-20 раз; включать на чанках старше 7 дней
  • Continuous Aggregates — материализованные представления с автообновлением; запросы к агрегатам работают мгновенно
  • InfluxDB 3.0 на Apache Arrow даёт лучшее сжатие (30x) и производительность для чистых time series

Чем timeseries данные отличаются от обычных?

Три ключевых свойства, определяющих архитектуру:

Immutability, данные почти никогда не обновляются после записи. Запись датчика за прошлую секунду не меняется. Это позволяет применять агрессивное сжатие и особые стратегии хранения.

Упорядоченность по времени, большинство запросов содержат условие WHERE time > X AND time < Y. Данные физически хранятся в порядке времени для быстрого диапазонного чтения.

Retention policy, старые данные обычно удаляются или агрегируются (downsampling). Хранить посекундные метрики за 5 лет нет смысла, но месячные агрегаты, полезны.

TimescaleDB: PostgreSQL для временных рядов

TimescaleDB, расширение PostgreSQL, превращающее обычную таблицу в гипертаблицу (hypertable). Данные автоматически разбиваются на чанки по времени, каждый из которых хранится отдельно.

Установка и создание гипертаблицы

-- В PostgreSQL с установленным расширением
CREATE EXTENSION IF NOT EXISTS timescaledb;

CREATE TABLE metrics (
 time TIMESTAMPTZ NOT NULL,
 device_id TEXT NOT NULL,
 metric_name TEXT NOT NULL,
 value DOUBLE PRECISION
);

-- Превращаем в гипертаблицу с чанками по 1 дню
SELECT create_hypertable('metrics', 'time', chunk_time_interval => INTERVAL '1 day');

-- Создаём индекс для запросов по device_id
CREATE INDEX ON metrics (device_id, time DESC);

После этого INSERT работает как обычно, но TimescaleDB автоматически распределяет данные по чанкам.

Запросы с time_bucket

Killer feature TimescaleDB, функция time_bucket, аналог DATE_TRUNC но более гибкая:

-- Средняя температура по 5-минутным интервалам за последний час
SELECT
 time_bucket('5 minutes', time) AS bucket,
 device_id,
 AVG(value) AS avg_temp,
 MAX(value) AS max_temp
FROM metrics
WHERE
 metric_name = 'temperature'
 AND time >= NOW() - INTERVAL '1 hour'
GROUP BY bucket, device_id
ORDER BY bucket DESC;

Запрос использует индекс по времени и сканирует только 12 чанков (последний час) вместо всей таблицы.

Политики удаления и сжатия

-- Автоматически удалять данные старше 90 дней
SELECT add_retention_policy('metrics', INTERVAL '90 days');

-- Включить сжатие для старых чанков (старше 7 дней)
ALTER TABLE metrics SET (
 timescaledb.compress,
 timescaledb.compress_segmentby = 'device_id',
 timescaledb.compress_orderby = 'time DESC'
);

SELECT add_compression_policy('metrics', INTERVAL '7 days');

Сжатие снижает занимаемое место в 10–20 раз для числовых данных.

Непрерывные агрегаты (Continuous Aggregates)

Вместо того чтобы каждый раз считать агрегаты на лету, TimescaleDB может хранить их материализованно и обновлять автоматически:

CREATE MATERIALIZED VIEW metrics_hourly
WITH (timescaledb.continuous) AS
SELECT
 time_bucket('1 hour', time) AS hour,
 device_id,
 metric_name,
 AVG(value) AS avg_value,
 MIN(value) AS min_value,
 MAX(value) AS max_value,
 COUNT(*) AS sample_count
FROM metrics
GROUP BY hour, device_id, metric_name;

-- Автообновление каждые 10 минут
SELECT add_continuous_aggregate_policy('metrics_hourly',
 start_offset => INTERVAL '3 hours',
 end_offset => INTERVAL '10 minutes',
 schedule_interval => INTERVAL '10 minutes'
);

Запросы к metrics_hourly работают мгновенно даже при миллиардах строк в metrics.

InfluxDB: специализированная timeseries БД

InfluxDB, база данных, спроектированная с нуля для временных рядов. Версия 3.0 использует Apache Arrow и Parquet под капотом, обеспечивая исключительную производительность.

Концепции InfluxDB

  • Measurement, аналог таблицы (cpu, temperature, requests)
  • Tags, индексированные строковые метаданные (host=server1, region=eu)
  • Fields, числовые значения (usage_user=45.2, usage_idle=54.8)
  • Timestamp, временная метка записи

Запись данных через Python

import influxdb_client
from influxdb_client import InfluxDBClient, Point
from influxdb_client.client.write_api import SYNCHRONOUS
from datetime import datetime

client = InfluxDBClient(
 url="http://localhost:8086",
 token="my-token",
 org="my-org"
)

write_api = client.write_api(write_options=SYNCHRONOUS)

# Запись одной точки
point = (
 Point("cpu_usage")
 .tag("host", "server1")
 .tag("region", "eu-west")
 .field("usage_user", 45.2)
 .field("usage_system", 12.1)
 .field("usage_idle", 42.7)
 .time(datetime.utcnow())
)

write_api.write(bucket="metrics", org="my-org", record=point)

# Пакетная запись для высокой нагрузки
with client.write_api() as write_api:
 points = [
 Point("temperature")
 .tag("device_id", f"sensor_{i}")
 .field("value", 20.0 + i * 0.1)
 for i in range(1000)
 ]
 write_api.write(bucket="metrics", record=points)

Flux и SQL запросы

InfluxDB 3.0 поддерживает SQL:

-- Среднее значение CPU за последние 24 часа по хостам
SELECT
 DATE_BIN(INTERVAL '1 hour', time, '1970-01-01') AS hour,
 host,
 AVG(usage_user) AS avg_cpu
FROM cpu_usage
WHERE time >= NOW() - INTERVAL '24 hours'
GROUP BY hour, host
ORDER BY hour DESC;

Continuous Aggregates: материализованные представления

Вместо того чтобы каждый раз считать агрегаты на лету, TimescaleDB хранит их материализованно и обновляет автоматически:

CREATE MATERIALIZED VIEW metrics_hourly
WITH (timescaledb.continuous) AS
SELECT
    time_bucket('1 hour', time) AS hour,
    device_id,
    metric_name,
    AVG(value) AS avg_value,
    MIN(value) AS min_value,
    MAX(value) AS max_value,
    COUNT(*) AS sample_count
FROM metrics
GROUP BY hour, device_id, metric_name;

-- Автообновление каждые 10 минут
SELECT add_continuous_aggregate_policy('metrics_hourly',
    start_offset => INTERVAL '3 hours',
    end_offset => INTERVAL '10 minutes',
    schedule_interval => INTERVAL '10 minutes'
);

Запросы к metrics_hourly работают мгновенно даже при миллиардах строк в metrics.

TimescaleDB vs InfluxDB

Разница не в скорости — обе справляются с типичными нагрузками мониторинга. Разница в том, откуда вы стартуете и что нужно.

TimescaleDB — это PostgreSQL. Joins с таблицей пользователей, транзакции, знакомый SQL, весь существующий инструментарий работает без изменений. Настройка гипертаблицы занимает 15 минут. Если уже есть Postgres, добавить timeseries-хранение — одна команда CREATE EXTENSION.

InfluxDB 3.0 строится на Apache Arrow и Parquet, что даёт более агрессивное сжатие (до 30x против 20x у TimescaleDB) и лучшую производительность на сверхвысоких частотах записи. Архитектура заточена под сценарии, где данные никогда не пересекаются с реляционными таблицами: чистый IoT или метрики без связей.

КритерийTimescaleDBInfluxDB 3.0
ОсноваPostgreSQL extensionStandalone server
SQLПолный PostgreSQL SQLSQL (ограниченный)
Joins с реляционными даннымиДаНет
Сжатие10-20x25-30x
Запись (max)~1M rows/sec~5M rows/sec
Операционная сложностьНизкая (это Postgres)Средняя

Итог

TimescaleDB — первый выбор для команд, которые уже используют PostgreSQL. Миграция минимальна, SQL-знания применимы. InfluxDB лучше для чистых time series сценариев с максимальной производительностью записи и агрессивным сжатием.

Хотите узнать больше о специализированных базах данных? Следующая тема — графовые базы данных: Neo4j и Cypher.