Для чего использовал ClickHouse?

«Для чего использовал ClickHouse?» — вопрос из категории Базы данных, который задают на 26% собеседований Node.js Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Я использовал ClickHouse в проектах на Node.js для аналитической обработки больших объемов данных в реальном времени. Это колоночная OLAP-СУБД, идеально подходящая для сценариев, где важна скорость агрегации и чтения.

Конкретные кейсы применения:

  1. Аналитика пользовательских событий: Хранение и агрегация миллиардов событий (клики, просмотры, действия в приложении) для построения дашбордов.
  2. Мониторинг и логирование: Агрегация логов сервисов и метрик (например, время ответа API, ошибки) для быстрого поиска аномалий.
  3. Финансовая отчетность: Быстрое вычисление сложных агрегатов по транзакциям за большие периоды.

Пример интеграции с Node.js:

const { ClickHouse } = require('clickhouse');

const clickhouse = new ClickHouse({
    url: 'http://localhost',
    port: 8123,
    debug: false,
    basicAuth: {
        username: 'default',
        password: '',
    },
    format: 'json', // Получаем ответ в виде JSON
});

// Вставка данных (высокая скорость)
async function insertEvent(event) {
    const query = `INSERT INTO analytics.events FORMAT JSONEachRow`;
    await clickhouse.insert(query, [event]).toPromise();
}

// Аналитический запрос с агрегацией
async function getDailyStats(date) {
    const query = `
        SELECT 
            toDate(timestamp) as day,
            event_type,
            count() as events_count,
            uniq(user_id) as unique_users
        FROM analytics.events
        WHERE day = '${date}'
        GROUP BY day, event_type
        ORDER BY events_count DESC
    `;
    const rows = await clickhouse.query(query).toPromise();
    return rows;
}

Почему ClickHouse, а не другая БД? Для аналитических запросов с GROUP BY и агрегатными функциями (count, sum, uniq) на терабайтах данных он работает на порядки быстрее традиционных row-based SQL-баз (PostgreSQL, MySQL) благодаря колоночному хранению, сжатию данных и векторized execution.