В прошлом уроке мы выполнили первые запросы и посмотрели DESCRIBE таблицы зон. В ответе у каждой колонки был тип: UInt16, String, Date. В PostgreSQL мы привыкли писать integer и text и не думать о размерах. В ClickHouse тип стоит выбирать внимательнее, и вот почему.
Коробки по размеру
Помнишь колоночное хранение? Колонка лежит на диске отдельным файлом, а внутри это просто массив значений одного размера, одно за другим. Номер зоны в «Гонце» от 1 до 12. Если хранить его 8-байтным числом, массив из миллиарда номеров весит 8 ГБ. Если однобайтным, 1 ГБ. Аналитический запрос читает колонку целиком, так что тип напрямую задаёт, сколько байт придётся прочитать.
Это как переезд: книги можно сложить в коробки из-под холодильника, а можно в коробки по размеру. Книг столько же, но машин понадобится в восемь раз меньше.
Целые числа
У целых два параметра: размер в битах и знак.
| Тип | Байт | Диапазон |
|---|---|---|
UInt8 | 1 | от 0 до 255 |
UInt16 | 2 | от 0 до 65 535 |
UInt32 | 4 | от 0 до 4 294 967 295 |
UInt64 | 8 | до 18 с лишним квинтиллионов |
Int8, Int16, Int32, Int64 | 1, 2, 4, 8 | то же, но половина диапазона уходит на отрицательные |
U значит беззнаковое. В таблице заказов «Гонца» zone_id это UInt16, а id это UInt32: заказов будет больше 65 тысяч, но точно меньше четырёх миллиардов.
ClickHouse и литералам в запросе подбирает самый маленький подходящий тип: 1 это UInt8, 300 это UInt16, -1 это Int8. При арифметике тип результата расширяется: 255 + 1 даст 256 типа UInt16, переполнения не будет.
А вот при записи в колонку переполнение тихое. Число 256 в колонке UInt8 превратится в 0, и ClickHouse не скажет ни слова. Проверим это в песочнице ниже.
Дробные числа и деньги
Float32 и Float64 это обычные числа с плавающей точкой, как double в других языках. Они быстрые, но неточные: 0.1 + 0.2 даст 0.30000000000000004.
Для денег это не годится. Цены заказов хранятся в Decimal(8, 2): Decimal на восемь цифр, две из них после запятой. Лишние знаки после запятой отбрасываются: 1.005 запишется как 1.00.
Ещё одна особенность: оператор / в ClickHouse всегда возвращает Float64. 7 / 2 это 3.5, а не 3, как в PostgreSQL. Целочисленное деление пишется функцией intDiv(7, 2).
урок из курса
Урок из курса «ClickHouse и аналитические базы». Курс покупается один раз и остаётся навсегда: 500 ₽.
Оплата пока не подключена: премиум и курсы открываются промокодом.