исправлены предыдущие ошибки, добавлен полностью блок по кликхаус и пет-проект

This commit is contained in:
Dmitry Medvedev
2026-09-15 15:34:46 +05:00
parent 297df348c1
commit fb0f37912d
11 changed files with 1235 additions and 2 deletions
@@ -0,0 +1,111 @@
# Задачи на отработку:
### **Задача 1.**
Таблица `sales`
| id | region | sale_date | amount |
| --- | --- | --- | --- |
| 1 | RU | 2024-05-01 | 100.0 |
| 2 | RU | 2024-05-15 | 120.0 |
| 3 | US | 2024-06-01 | 90.0 |
| 4 | US | 2024-07-03 | 150.0 |
| 5 | DE | 2024-07-04 | 160.0 |
1. Создай таблицу с `PARTITION BY toYYYYMM(sale_date)`.
CREATE TABLE IF NOT EXISTS sales (
id UInt8,
region String,
sale_sate DateTime64,
amount Float64
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(sale_date)
ORDER BY (sale_date, region);
2. Выполни `ALTER TABLE ... DROP PARTITION '202405'`.
УДАЛИЛАСЬ ПАРТИЦИЯ
3. Что произойдет, если не указывать `PARTITION BY`?
ЕСЛИ МЫ ГОВОРИМ ПРО ПРОЦЕСС СОЗДАНИЯ, ТО В ТАКОМ СЛУЧАЕ ВСЕ ДАННЫЕ БУДУТ НАХОДИТЬСЯ ПО УМОЛЧАНИЮ В ОДНОЙ ПАРТИЦИИ.
### **Задача 2.**
Есть таблица `events`, и ты хочешь логически хранить данные **по типу события**.
| id | event_type | event_date |
| --- | --- | --- |
| 1 | login | 2024-06-01 |
| 2 | click | 2024-06-01 |
| 3 | click | 2024-06-02 |
| 4 | purchase | 2024-06-03 |
| 5 | login | 2024-06-04 |
1. Создай таблицу с `PARTITION BY event_type`.
CREATE TABLE IF NOT EXISTS sales (
id UInt8,
event_type String,
event_date Date
)
ENGINE = MergeTree()
PARTITION BY event_type
ORDER BY (event_type, event_date);
2. Удали все события `click` (подсказка: это `ALTER TABLE DROP PARTITION 'click'`).
3. Чем такой подход может быть опасен (подумай про кардинальность значений)?
СЕЙЧАС СОБЫТИЙ ПО ФАКТУ 3, ЭТО МАЛО И УДАЛЕНИЕ БУДЕТ ПРОИСХОДИТЬ БЫСТРО, А ЕСЛИ ПАРТИЦИЙ БУДЕТ 1000, ТО В ТАКОМ СЛУЧАЕ СИСТЕМА БУДЕТ ТОРМОЗИТЬ.
### **Задача 3.**
Ты хочешь разбить таблицу `logs` на 100 партиций по `user_id`, чтобы равномерно распределить объём данных.
| id | user_id | log_time |
| --- | --- | --- |
| 1 | 123 | 2024-07-17 10:00:00 |
| 2 | 456 | 2024-07-17 10:01:00 |
| 3 | 789 | 2024-07-17 10:02:00 |
1. Создай таблицу с `PARTITION BY cityHash64(user_id) % 100`.
CREATE TABLE IF NOT EXISTS logs (
id UInt32,
user_id UInt32,
log_time DateTime64
)
ENGINE = MergeTree()
PARTITION BY cityHash64(user_id) % 100
ORDER BY (user_id, log_time);
2. Что ты выиграешь с точки зрения баланса?
Я СБАЛАНСИРОВАННО РАЗДЕЛЮ ВСЕ ЛОГИ ПО ПАРТИЦИЯМ ПО УНИКАЛЬНОМУ ЮЗЕР АЙДИ
3. Почему такой тип `PARTITION` не ускорит `SELECT * WHERE user_id = 456`?
ПОТОМУ ЧТО В ТАКОМ СЛУЧАЕ ПРИДЕТСЯ ВСЕ РАВНО СКАНИРОВАТЬ ВСЕ ПАРТИЦИИ, ТО ЕСТЬ ВСЮ БАЗУ ДАННЫХ, ВВИДУ ТОГО, ЧТО АЙДИШНИК 456 КЛИКХАУЦС НЕ СМОЖЕТ ПОДСТАВИТЬ В
cityHash64(user_id) ДЛЯ РАСЧЕТА В ХЭЩ ФУНКЦИИ. ПОЭТОМУ ОПТИМИЗАТОРУ НЕОБХОДИМО БУДЕТ ЗАГЛЯНУТЬ В 100 ФАЙЛОВ НА ДИСКЕ .
### **Задача 4.**
В таблице `visits` данные зависят от региона и времени.
| id | region | visit_date |
| --- | --- | --- |
| 1 | RU | 2024-06-01 |
| 2 | RU | 2024-06-15 |
| 3 | US | 2024-06-03 |
| 4 | US | 2024-07-01 |
| 5 | RU | 2024-07-05 |
1. Создай таблицу с `PARTITION BY (region, toYYYYMM(visit_date))`.
CREATE TABLE IF NOT EXISTS visits (
id UInt8,
region String,
visit_date Date
)
ENGINE = MergeTree()
PARTITION BY (region, toYYYYMM(visit_date))
ORDER BY (visit_date, id);
2. Как будет выглядеть имя партиции?
"RU-202406"
"US-202406"
"US-202407"
"RU-202407"
3. Сможешь ли ты эффективно удалить **все июльские данные по `RU`**?
НЕТ КОНЕЧНО, ТАК КАК ЭТИ ДАННЫЕ НАХОДЯТСЯ В ДВУХ ПАРТИЦИЯХ, ТО НЕОБХОДИМО БУДЕТ С ПОМОЩЬЮ УДАЛЯТЬ ЧЕРЕЗ "RU-202407".