Что такое TimescaleDB?
TimescaleDB — это специализированная база данных временных рядов (time-series), построенная как расширение PostgreSQL. Она объединяет масштабируемость NoSQL систем с привычностью и надёжностью SQL, оптимизированная для работы с временными данными.
Ключевые особенности TimescaleDB
- Полная SQL совместимость — все возможности PostgreSQL
- Автоматическое партицирование — по времени и пространству
- Hypertables — абстракция над партицированными таблицами
- Непрерывные агрегаты — предвычисленные представления
- Сжатие данных — экономия места на диске
- Политики хранения — автоматическое удаление старых данных
Установка TimescaleDB
Установка на Ubuntu/Debian:
1# Добавление репозитория TimescaleDB
2echo "deb https://packagecloud.io/timescale/timescaledb/ubuntu/ $(lsb_release -c -s) main" | sudo tee /etc/apt/sources.list.d/timescaledb.list
3wget --quiet -O - https://packagecloud.io/timescale/timescaledb/gpgkey | sudo apt-key add -
4
5# Установка
6sudo apt-get update
7sudo apt-get install timescaledb-2-postgresql-14
8
9# Настройка PostgreSQL
10sudo timescaledb-tune
11sudo systemctl restart postgresql
12
13# Создание расширения в базе данных
14psql -d mydb -c "CREATE EXTENSION IF NOT EXISTS timescaledb;"
Установка через pip для разработки:
Создание hypertable
1-- Создание обычной таблицы
2CREATE TABLE sensor_data (
3 time TIMESTAMPTZ NOT NULL,
4 sensor_id INTEGER,
5 temperature DOUBLE PRECISION,
6 humidity DOUBLE PRECISION,
7 location TEXT
8);
9
10-- Преобразование в hypertable
11SELECT create_hypertable('sensor_data', 'time');
12
13-- Создание индексов для лучшей производительности
14CREATE INDEX ON sensor_data (sensor_id, time DESC);
15CREATE INDEX ON sensor_data (location, time DESC);
Работа с данными временных рядов
1-- Вставка данных
2INSERT INTO sensor_data (time, sensor_id, temperature, humidity, location)
3VALUES
4 (NOW(), 1, 22.5, 65.2, 'office'),
5 (NOW() - INTERVAL '1 minute', 1, 22.3, 65.5, 'office'),
6 (NOW() - INTERVAL '2 minutes', 2, 21.8, 64.1, 'warehouse');
7
8-- Запросы с временными функциями
9SELECT
10 time_bucket('1 hour', time) AS hour,
11 sensor_id,
12 AVG(temperature) as avg_temp,
13 MAX(temperature) as max_temp,
14 MIN(temperature) as min_temp
15FROM sensor_data
16WHERE time >= NOW() - INTERVAL '1 day'
17GROUP BY hour, sensor_id
18ORDER BY hour DESC;
19
20-- Поиск аномалий
21SELECT time, sensor_id, temperature
22FROM sensor_data
23WHERE temperature > (
24 SELECT AVG(temperature) + 2 * STDDEV(temperature)
25 FROM sensor_data
26 WHERE time >= NOW() - INTERVAL '1 hour'
27);
Непрерывные агрегаты
1-- Создание непрерывного агрегата для почасовой статистики
2CREATE MATERIALIZED VIEW hourly_stats
3WITH (timescaledb.continuous) AS
4SELECT
5 time_bucket('1 hour', time) AS hour,
6 sensor_id,
7 AVG(temperature) as avg_temp,
8 MAX(temperature) as max_temp,
9 MIN(temperature) as min_temp,
10 COUNT(*) as readings_count
11FROM sensor_data
12GROUP BY hour, sensor_id;
13
14-- Настройка автоматического обновления
15SELECT add_continuous_aggregate_policy('hourly_stats',
16 start_offset => INTERVAL '3 hours',
17 end_offset => INTERVAL '1 hour',
18 schedule_interval => INTERVAL '30 minutes');
Политики хранения и сжатия
1-- Настройка автоматического удаления старых данных
2SELECT add_retention_policy('sensor_data', INTERVAL '90 days');
3
4-- Настройка сжатия данных старше 7 дней
5ALTER TABLE sensor_data SET (
6 timescaledb.compress,
7 timescaledb.compress_segmentby = 'sensor_id',
8 timescaledb.compress_orderby = 'time DESC'
9);
10
11SELECT add_compression_policy('sensor_data', INTERVAL '7 days');
Интеграция с Python
1import psycopg2
2import pandas as pd
3from datetime import datetime, timedelta
4
5# Подключение к базе данных
6conn = psycopg2.connect(
7 host="localhost",
8 database="timeseries_db",
9 user="postgres",
10 password="password"
11)
12
13# Массовая вставка данных
14def insert_sensor_data(sensor_id, readings):
15 cursor = conn.cursor()
16
17 insert_query = """
18 INSERT INTO sensor_data (time, sensor_id, temperature, humidity)
19 VALUES %s
20 """
21
22 data = [(reading['time'], sensor_id, reading['temp'], reading['humidity'])
23 for reading in readings]
24
25 psycopg2.extras.execute_values(cursor, insert_query, data)
26 conn.commit()
27
28# Запрос данных с pandas
29def get_sensor_stats(sensor_id, hours_back=24):
30 query = """
31 SELECT
32 time_bucket('1 hour', time) as hour,
33 AVG(temperature) as avg_temp,
34 MAX(temperature) as max_temp,
35 MIN(temperature) as min_temp
36 FROM sensor_data
37 WHERE sensor_id = %s AND time >= NOW() - INTERVAL '%s hours'
38 GROUP BY hour
39 ORDER BY hour
40 """
41
42 return pd.read_sql_query(query, conn, params=[sensor_id, hours_back])
43
44# Поиск аномалий
45def detect_anomalies(sensor_id, threshold=2.0):
46 query = """
47 WITH stats AS (
48 SELECT AVG(temperature) as mean_temp,
49 STDDEV(temperature) as stddev_temp
50 FROM sensor_data
51 WHERE sensor_id = %s AND time >= NOW() - INTERVAL '1 day'
52 )
53 SELECT time, temperature,
54 ABS(temperature - stats.mean_temp) / stats.stddev_temp as z_score
55 FROM sensor_data, stats
56 WHERE sensor_id = %s
57 AND time >= NOW() - INTERVAL '1 hour'
58 AND ABS(temperature - stats.mean_temp) / stats.stddev_temp > %s
59 ORDER BY time DESC
60 """
61
62 return pd.read_sql_query(query, conn, params=[sensor_id, sensor_id, threshold])
Мониторинг и оптимизация
1-- Просмотр информации о hypertables
2SELECT * FROM timescaledb_information.hypertables;
3
4-- Статистика по chunks (партициям)
5SELECT * FROM timescaledb_information.chunks
6WHERE hypertable_name = 'sensor_data'
7ORDER BY range_start DESC;
8
9-- Статистика сжатия
10SELECT
11 hypertable_name,
12 total_chunks,
13 number_compressed_chunks,
14 before_compression_total_bytes,
15 after_compression_total_bytes,
16 compression_ratio
17FROM timescaledb_information.compression_stats;
Случаи использования TimescaleDB
- IoT и сенсорные данные — сбор метрик с устройств
- Мониторинг инфраструктуры — DevOps метрики
- Финансовые данные — цены акций, торговые данные
- Логирование приложений — анализ производительности
- Промышленная аналитика — данные с производственных линий
Преимущества TimescaleDB
- Полная совместимость с PostgreSQL и его экосистемой
- Автоматическая оптимизация для временных данных
- Эффективное сжатие и управление хранением
- Масштабируемость до миллионов записей в секунду
- Богатые возможности аналитики с SQL
Рекомендации по использованию
- Выбирай подходящий интервал партицирования на основе паттернов запросов
- Используй непрерывные агрегаты для часто выполняемых аналитических запросов
- Настрой политики сжатия и хранения с самого начала
- Создавай индексы на часто используемые в WHERE колонки
FAQ
В чём разница между TimescaleDB и InfluxDB?
TimescaleDB предоставляет полную SQL совместимость и интеграцию с PostgreSQL экосистемой, в то время как InfluxDB имеет собственный язык запросов и оптимизирован исключительно для временных рядов.
Можно ли использовать TimescaleDB для обычных реляционных данных?
Да, поскольку TimescaleDB — это расширение PostgreSQL, ты можешь использовать обычные таблицы наряду с hypertables в одной базе данных.