Добавить в корзинуПозвонить
Найти в Дзене
Трофим Воробьев

ClickHouse не тормозит, но не умеет в DML. Часть 2. Append-only.

Append-only — целебная пилюля для ClickHouse. Разберем что это, и как этим пользоваться. Напоминаю, что ClickHouse очень плохо умеет в DML — рекомендую к прочтению первую статью. Ну а решение очень простое — Append-only. Это концепция, согласно которой данные в таблицы только добавляются. Никаких обновлений. Создадим таблицу для теста: create table t1 engine=MergeTree order by id as (select 1 as id, 'qq' as name union all select 2 as id, 'bb' as name); А теперь представим, что при id=1 хотим, чтобы name='xx' вместо 'qq'. Для этого мы просто вставляем новую запись: insert into t1 values(1, 'xx'); Теперь встает логичный вопрос: а как мы поймем, какая из записей актуальная? Очевидно, нужно версионирование данных. Способов это сделать много, но покажу самый элегантный и беспроблемный, на мой взгляд. Нам понадобится добавить колонку с временем вставки записи в таблицу. Таким образом, актуальная запись будь та, у которой наибольшее время. Для этого лучше пересоздать таблицу во избежание про
Оглавление

Append-only — целебная пилюля для ClickHouse. Разберем что это, и как этим пользоваться.

Напоминаю, что ClickHouse очень плохо умеет в DML — рекомендую к прочтению первую статью.

Ну а решение очень простое — Append-only. Это концепция, согласно которой данные в таблицы только добавляются. Никаких обновлений.

Перейдем сразу к примеру:

Создадим таблицу для теста:

create table t1 engine=MergeTree order by id as (select 1 as id, 'qq' as name union all select 2 as id, 'bb' as name);

-2

А теперь представим, что при id=1 хотим, чтобы name='xx' вместо 'qq'. Для этого мы просто вставляем новую запись:

insert into t1 values(1, 'xx');

-3

Теперь встает логичный вопрос: а как мы поймем, какая из записей актуальная? Очевидно, нужно версионирование данных. Способов это сделать много, но покажу самый элегантный и беспроблемный, на мой взгляд.

Нам понадобится добавить колонку с временем вставки записи в таблицу. Таким образом, актуальная запись будь та, у которой наибольшее время. Для этого лучше пересоздать таблицу во избежание проблем.

CREATE TABLE default.t1

(

`id` UInt8,

`name` String,

`dt_load` DateTime DEFAULT now()

)

ENGINE = MergeTree

ORDER BY id

SETTINGS index_granularity = 8192;

Мы добавили в таблицу колонку dt_load, значение даты которой определяется в момент вставки записи в таблицу. now() - текущее время. DEFAULT - выбрать now(), если пользователь ничего не вставляет в колонку. Таким образом мы можем как сами определять время для версионирования, так и возложить эту ношу на клик (что и сделаем).

Вставляем записи:

insert into t1 (id, name) values (1, 'qq'), (2, 'bb');

-4

Видим, что у обеих записей одинаковое время. Это тот самый момент времени, когда мы добавили данные в таблицу.

Ну а теперь вставляем нужное нам значение:

insert into t1 (id, name) values (1, 'xx');

-5

И теперь видим результат: у нас есть версионирование. Основная проблема решена — мы избавились от DML. Но получили теоретическую другую - дублирование записей. И если хранение истории версионирования не нужно - то можно использовать движок ReplacingMergeTree вместо MergeTree. Он поможет удалить дубли, оставив только ту запись, у которой dt_load наибольший.

Заключение:

Append-only + версионирование — концепция, позволяющая избавиться от дорогостоящих DML запросов. ClickHouse без нее скорее обуза, нежели буст для бизнеса.

Из этих двух статей мы поняли, ClickHouse - штука мощная, но со своим характером.

Осваивать этого зверя можно двумя способами. Первый - героический: месяцами вчитываться в документацию, собирать грабли по крупицам из форумов (привет Хабр) и всевозможных чатов. Второй - прагматичный: пройти бесплатный курс, состоящий из 5 часов видеолекций, от автора этой статьи. В нем все шишки уже набиты, а опыт упакован в понятные уроки.

Выбирайте путь умного, ведь время=деньги.
ClickHouse: быстрый старт