В целом clickhouse реализует sql и запросы похожи не те, которые используются при работе в mysql, но есть ряд отличий(с ними познакомимся дальше).
Создание таблицы может выглядеть так
```clickhouse
CREATE TABLE history
(
uuid UUID,
entity ENUM('user', 'device'),
entity_id String,
action Int16,
field String,
value Nullable(String),
created_by Int32,
created_at DateTime
)
Engine MergeTree()
PARTITION BY toYYYYMM(created_at)
PRIMARY KEY (created_at, uuid)
ORDER BY (created_at, uuid);
```
Нужно скопировать запрос в терминал и выполнить (ctrl + enter)
В данном случае мы создали простую таблицу для хранения истории
В clickhouse нет auto increment поэтому в качестве primary key используется uuid.
В данном случае создана партицированная таблица с разбивкой по месяцам, поэтому мы обязаны при создании добавить поле в PRIMARY KEY и ORDER BY
Партиции позволяют ускорить запрос за счет того что выборка получается меньше по размерам. Вместо 1 большой таблицы на 10 миллионов записей, можно получить 10 виртуальных таблиц по 1 миллиону.
С точки зрения использования запрос не меняется. Мы по прежнему работаем с 1 таблицей. Всю магию по определению партиция и объединению результатов выборки clickhouse реализует под капотом.
Дальше в запросе видно, что мы указали engine для таблицы. В отличие от mysql, где на проекте обычно используется всегда один движок, в clickhouse нужно иметь понятие об их существовании и отличиях.
Официальная документация тут https://clickhouse.com/docs/ru/engines/table-engines.
Каждый движок несет свои уникальные возможности.
Например:
- MergeTree - позволяет использовать партиции и быстро обрабатывает insert запросы
- MySql - позволяет делать запросы к mysql через clickhouse и тем самым избежать дублирования данных
- File - позволяет писать / читать из конкретного файла. Может быть удобно для просмотра логов, либо для быстрого импорта данных в основную таблицу на основе которой уже выводится статистика.
## Модификация полей таблицы (DDL)
Модификация полей в целом аналогична mysql
Выполним запрос и описание таблицы
```clickhouse
ALTER TABLE history MODIFY COLUMN created_by Nullable(Int32)
```
Посмотрим DDL
![img.png](images/ddl.png)
Видим такой результат
```clickhouse
-- auto-generated definition
create table history
(
uuid UUID,
entity Enum8('user' = 1, 'device' = 2),
entity_id String,
action Int16,
field String,
value Nullable(String),
created_by Nullable(Int32),
created_at DateTime
)
engine = MergeTree PARTITION BY toYYYYMM(created_at)
PRIMARY KEY (created_at, uuid)
ORDER BY (created_at, uuid)
SETTINGS index_granularity = 8192;
```
Текущая схема соответствует ожидаемой структуре.
## Вставка данных
Вставка данных похожа на mysql.
Выполните в терминале
```clickhouse
insert into history SELECT generateUUIDv4(), 'user', generateUUIDv4(), rand32(), 'first_name', 'Anakin', 3, now() - interval 100 day;
insert into history SELECT generateUUIDv4(), 'user', generateUUIDv4(), rand32(), 'last_name', 'Skywalker', 2, now() - interval 50 day;
insert into history SELECT generateUUIDv4(), 'user', generateUUIDv4(), rand32(), 'age', '33', 1, now() - interval 10 day;
insert into history SELECT generateUUIDv4(), 'user', generateUUIDv4(), rand32(), 'first_name', 'Denis', 2, now();
```
Данные должны успешно вставиться и быть доступны на чтение
Здесь видно, что данные разбиты на 5 частей, несмотря на то что у нас три записи попадают в один месяц. При вставке clickhouse вставляет данные в отдельные куски и затем в фоне может их обрабатывать и объединять для оптимизации.
insert into history SELECT generateUUIDv4(), 'device', generateUUIDv4(), rand32(), 'first_name', 'Denis', null, now();
```
Вставка происходит успешно. Несмотря на то, что мы передаем null в not nullable поле created_by. В данном случае значение привелось к 0 и сохранилось в базе
А теперь попробуем вставить такие данные
```clickhouse
insert into history SELECT generateUUIDv4(), 'device2', generateUUIDv4(), rand32(), 'first_name', 'Denis', 3, now();
Несмотря на то, что есть возможность редактировать данные, не стоит этим злоупотреблять. Если единовременно будет много мутаций в обработке, то это плохо скажется на производительности системы и может привести к ошибкам накатки мутаций.