Learning Platform
Глоссарий Troubleshooting
Урок 02.03 · 25 мин
Средний
EncodingDictionary EncodingRLEDelta EncodingBit-Packing

Основы кодирования данных

Кодирование ≠ Компрессия

Кодирование (encoding) и компрессия (compression) часто путают, но это разные стадии конвейера:

  • Кодирование — преобразует данные в более компактное представление, сохраняя семантику. Закодированные данные можно читать без полной декомпрессии.
  • Компрессия — применяет общий алгоритм сжатия (Snappy, Zstd) к уже закодированным данным. Результат — бинарный blob, который нужно полностью распаковать.

Кодирование работает до компрессии и использует знание о типе данных. Компрессия работает после и обрабатывает данные как поток байтов.

Encoding → Compression Pipeline

Raw данные колонки

Исходные значения колонки — например, 1M строк с колонкой department
Stage 1: Encoding

Закодированные данные (меньше, но читаемы)

Encoding использует знание о типе: dictionary для строк с повторами, delta для монотонных чисел, RLE для серий
Stage 2: Compression

Сжатые данные (минимальный размер)

Компрессия (Snappy/Zstd) сжимает уже компактные данные. Результат — binary blob для хранения

Dictionary Encoding

Самая распространённая кодировка для строковых данных с повторяющимися значениями.

Идея: вместо хранения полной строки каждый раз — создать словарь уникальных значений и заменить каждое вхождение на индекс в словаре.

Dictionary Encoding

До кодирования

Колонка department (1M строк)Каждая строка хранит полное текстовое значение — в среднем 11 байт на запись
1M × ~11 байт = ~11 MB

После кодирования

Словарь (4 записи)Словарь хранится один раз. При 4 уникальных значениях — всего ~40 байт
Индексы (1M записей)Каждая запись — 2 бита (4 значения = 2 бита на индекс). 1M × 2 бита ≈ 250 KB
~40 байт + 250 KB ≈ 250 KB (44x меньше)

Когда эффективно: колонка с низкой кардинальностью (мало уникальных значений). Типичные примеры: country, status, category, department.

Когда неэффективно: колонки с высокой кардинальностью (UUID, email, free-text). Словарь становится размером с оригинальные данные.

TIP

Parquet автоматически применяет dictionary encoding к каждой колонке. Если словарь превышает порог (по умолчанию 1 MB), Parquet переключается на plain encoding (fallback). Вы можете контролировать этот порог при записи.

Run-Length Encoding (RLE)

Заменяет последовательности одинаковых значений на пару (значение, количество).

Run-Length Encoding

До RLE

Колонка status (отсортирована)Данные отсортированы по status — одинаковые значения идут подряд длинными сериями
500K × active + 300K × inactive + 200K × deleted

После RLE

RLE-кодированные данныеТри пары вместо миллиона значений. RLE максимально эффективен на отсортированных данных.
3 пары вместо 1M значений

Когда эффективно: отсортированные данные или данные с длинными “сериями” одинаковых значений. Partition columns в Parquet — идеальный кандидат.

Когда неэффективно: случайно распределённые данные без повторяющихся серий.

NOTE

RLE часто комбинируется с dictionary encoding. Сначала значения заменяются на индексы словаря, затем серии одинаковых индексов кодируются RLE. Parquet использует именно эту комбинацию — RLE_DICTIONARY.

Delta Encoding

Хранит разницу между последовательными значениями вместо самих значений.

Delta Encoding

До delta encoding

Колонка timestamp (монотонная)Timestamps растут монотонно. Каждое значение занимает 8 байт (int64), но разница между соседними — маленькое число.
Каждое значение: 8 байт (int64)

После delta encoding

Base + дельтыБазовое значение + маленькие дельты (60 = 1 минута). Дельты помещаются в 1 байт вместо 8.
Base: 8 байт + каждая дельта: 1 байт (8x экономия)

Когда эффективно: монотонно растущие значения — timestamps, auto-increment IDs, event counters. Дельты маленькие → помещаются в меньше битов.

Когда неэффективно: случайные данные, где дельты такие же большие, как исходные значения.

Bit-Packing

Использует ровно столько битов, сколько нужно для представления значения, вместо стандартных 32 или 64 бит.

Если все значения в колонке помещаются в диапазон 0–15, нужно всего 4 бита на значение вместо 32:

Bit-Packing

Стандартное хранение (int32)

Значения 0–15Каждое число хранится как полный int32, хотя реально используются только 4 из 32 бит
32 бита на значение, 28 бит = нули

Bit-packed (4 бита)

Те же значения4 бита точно кодируют диапазон 0–15. 8 значений умещаются в 32 бита (один int32).
4 бита на значение → 8x экономия

Bit-packing часто применяется после dictionary encoding — индексы словаря обычно маленькие числа, которые помещаются в несколько бит.

Как кодировки комбинируются

Реальные форматы применяют несколько кодировок последовательно:

Типичный pipeline кодирования в Parquet

Raw строки: Engineering, Sales, Engineering, HR…

Исходные строковые значения с повторами — department, country, status и подобные колонки
1. Dictionary Encoding

Индексы: 0, 1, 0, 2, 0, 1, 0, 0, 2, 1…

Строки заменяются на числовые индексы словаря. Словарь: 0=Engineering, 1=Sales, 2=HR
2. RLE на индексах

RLE: (0, 3), (1, 1), (0, 2), (2, 1)…

Серии одинаковых индексов сжимаются в пары (значение, длина). Эффективно на отсортированных данных.
3. Bit-Packing на оставшихся

Packed: 2 бита на индекс

Индексы, которые не попали в RLE-серии, упаковываются по минимуму бит. 4 значения = 2 бита.
4. Compression (Snappy/Zstd)

Сжатый бинарный блок

Финальная компрессия общим алгоритмом. На уже закодированных данных даёт дополнительные 1.5–3x.

Ключевые выводы

  1. Кодирование использует знание о типе данных. Компрессия работает с байтами вслепую. Кодирование идёт первым.
  2. Dictionary encoding — для строк с повторами. Заменяет строки на маленькие числа. 10–100x сжатие на низкой кардинальности.
  3. RLE — для серий одинаковых значений. Максимально эффективен на отсортированных данных.
  4. Delta encoding — для монотонных последовательностей (timestamps, IDs). Хранит маленькие дельты вместо больших значений.
  5. Bit-packing — использует минимум бит. Часто применяется поверх dictionary индексов.
  6. Реальные форматы комбинируют кодировки: dictionary → RLE → bit-packing → compression.

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 4. В чём ключевая разница между кодированием (encoding) и компрессией (compression)?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 5