BI Consult Desktop Logo BI Consult Mobile Logo
  • Russian BI Исследование российских bi
  • Перейти на Fine BI
  • Контакты
  • +7 812 334-08-01
    +7 499 608-13-06
  • Отправить сообщение
  • Главная
  • Продукты Эксперт-BI
    • Дистрибуция
    • Розничная торговля
    • Производство
    • Операторы связи
    • Страхование
    • Банки
    • Лизинг
    • Логистика
    • Нефтегазовый сектор
    • Медицина
    • Сеть ресторанов
    • E-Commerce
    • Сельское хозяйство
    • Энергетика
    • FMCG
    • Девелоперы
    • Маркетплейсы
    • Пищевая промышленность
    • Фармацевтика
    • Построение Data Platform
    • Цифровая трансформация
    • Управление по KPI
    • Финансы
    • Продажи
    • Склад
    • HR
    • Маркетинг
    • Внутренний аудит
    • Категорийный менеджмент
    • S&OP и FP&A
    • Геоаналитика
    • Цепочки поставок (SCM)
    • AutoML
    • Process Mining
    • IBP
    • ИТ (CIO)
    • Закупки
  • Платформы
    • Системы бизнес-анализа (BI)
    • Интегрированное бизнес-планирование (IBP)
    • Хранилища данных (DWH / Lakehouse)
    • Каталоги данных (Data Catalog)
    • Системы ETL и ELT
    • AI / Исскуственный интеллект
    • Шина данных (ESB)
    • Система управления мастер-данными (MDM)
    • Семантический слой
  • Услуги
    • Переход на отечественные BI и DWH системы
    • Консалтинг
    • Пилотный проект
    • Обучение и сертификация
    • Бесплатное обучение
    • Поддержка
    • Технические задания
    • Сбор требований для проекта внедрения BI-системы
    • CI/CD для DWH
    • Аудит BI приложений и DWH
    • Выделенная команда
    • Настойка и поддержка баз данных
    • Разработка BI Стратегии
    • Styleguide для BI-системы
    • Как выбрать BI-систему
  • Курсы
    • Учебный курс Информационная грамотность (Data Literacy)
    • Учебный курс для бизнес-аналитиков
    • Учебный курс для системных аналитиков
    • Учебный курс по Data Governance
    • Учебный курс Как стать CDO
    • Учебный курс Современная архитектура хранилища данных
    • Учебный курс по Fine BI
    • Учебный курс по FineReport
    • Учебный курс по DWH
    • Учебный курс по Data Science (ML, AI)
    • Учебный курс по PostgreSQL
    • Учебный курс по Greenplum
    • Учебный курс по Apache Airflow и NiFi
    • Учебный курс по Open-source BI
    • Учебный курс по ClickHouse
    • Учебный курс по DataLens
    • Учебный курс по Loginom
    • Учебный курс по Modus BI и ETL
    • Учебный курс по Visiology
    • Учебный курс по dbt (Data Build Tool)
  • Компания
    • Руководство
    • Новости
    • Клиенты
    • Карьера
    • Скачать
    • Контакты

BI

  • FineBI
  • FineReport
  • FineDataLink
  • FineChatBI (FineAI)
  • Коннекторы данных из 1С в BI
  • Airflow / Nifi
  • Visiology
  • PIX BI
  • Modus BI
  • Yandex.DataLens
  • Open-source BI: Superset/Metabase
  • Luxms BI
  • AW BI + Alpha BI
  • FlyBI + Форсайт. Аналитическая Платформа
  • Loginom
  • Триафлай
  • AI / Исскуственный интеллект
  • Optimacros
  • Навигатор BI
  • Семантический слой

СУБД

  • Arenadata
  • ClickHouse
  • Greenplum
  • Postgres Professional
  • TData

Другое

  • Построение Data Platform
    • Аналитическое хранилище данных
    • Data Lake и Data Engineering
    • Подробнее про Data Lake
    • Внедрение Lakehouse
      • Apache Doris
      • StarRocks
      • Trino
    • Миграция витрин из пропиетарных DWH на новый стек
    • Учебный курс "Современная архитектура хранилища данных"
Главная » Курсы по системам бизнес-анализа и методологии » Учебный курс Современная архитектура хранилища данных » Выбор оптимальных форматов данных

Выбор оптимальных форматов данных

В современном мире, где данные стали новым нефтяным месторождением, правильный выбор форматов для их хранения и обработки является не технической мелочью, а стратегическим решением, напрямую влияющим на производительность, стоимость и масштабируемость всей вашей data-платформы. Наша компания, как ведущий интегратор решений в области управления данными, предлагает всесторонний анализ ключевых файловых форматов, используемых в дата-инженерии. Мы не просто перечислим их особенности, а глубоко погрузимся в технические детали, приведем практические примеры, выделим скрытые риски и распространенные ошибки внедрения, чтобы вы могли принимать взвешенные архитектурные решения. Этот материал предназначен для технических директоров, архитекторов данных и инженеров, стремящихся построить надежную и эффективную инфраструктуру.

 

Критическая важность выбора формата данных

Прежде чем выбирать инструменты, необходимо понять фундаментальные принципы. Формат данных — это не просто способ сериализации; это контракт между производителем и потребителем данных, определяющий эффективность хранения, скорость обработки, сложность эволюции схемы и общую стоимость владения. Ошибочный выбор на ранних этапах может привести к катастрофическим последствиям по мере роста объема данных: экспоненциальному росту затрат на хранение, неприемлемо долгому времени выполнения запросов, невозможности обеспечить консистентность данных и непреодолимым сложностям при интеграции с современными аналитическими системами.

Чтобы наглядно продемонстрировать работу с различными форматами, мы будем использовать универсальный генератор тестовых данных. Этот подход позволяет нам контролировать объем и структуру данных, обеспечивая чистоту эксперимента. Для реальных проектов мы всегда рекомендуем использовать максимально приближенные к продакшену данные.

 

 

Генератор тестовых данных:

import datetime
import uuid
import pandas as pd
from faker import Faker
def generate_users(size_of_generate: int = 1000) -> pd.DataFrame:
    """
    Функция-генератор тестовых данных о пользователях.
    Создает синтетический датасет с различными типами данных: UUID, даты, строки.
   
    :param size_of_generate: Количество генерируемых записей.
    :return: Pandas DataFrame с данными пользователей.
    """
    fake = Faker(locale="ru_RU")
    list_of_dict = []
    for _ in range(size_of_generate):
        dict_ = {
            "id": str(uuid.uuid4()),
            "created_at": fake.date_time_between(
                start_date=datetime.date(year=2024, month=1, day=1),
                end_date=datetime.date(year=2025, month=1, day=1),
            ),
            "updated_at": fake.date_time_between(
                start_date=datetime.date(year=2024, month=1, day=1),
                end_date=datetime.date(year=2025, month=1, day=1),
            ),
            "first_name": fake.first_name(),
            "last_name": fake.last_name(),
            "middle_name": fake.middle_name(),
            "birthday": fake.date_of_birth(
                minimum_age=18,
                maximum_age=70
            ),
            "email": fake.email(),
            "city": fake.city(),
        }
        list_of_dict.append(dict_)
   
    return pd.DataFrame(data=list_of_dict)

 

Apache Parquet: промышленный стандарт для аналитических нагрузок

Apache Parquet — это колоночный формат хранения, разработанный для высокой производительности при работе с большими объемами данных. Его основная философия — минимизация операций ввода-вывода и эффективное сжатие за счет хранения значений каждого столбца отдельно.

К основным характеристикам и преимуществам данного формата в первую очередь стоит указать  колоночную организацию хранения данных. Данные хранятся по столбцам, а не по строкам. Это означает, что для аналитического запроса, который затрагивает всего несколько столбцов (например, "посчитать средний возраст по городам"), система считывает только необходимые колонки city и birthday, а не весь файл целиком. Это радикально снижает дисковый I/O и ускоряет выполнение запросов в десятки и сотни раз.

Еще одним важным преимуществом Parquet является эффективное сжатие. Поскольку данные в одном столбце часто однородны (все значения одного типа и характера), алгоритмы сжатия (такие как Snappy, GZIP, LZO) работают исключительно эффективно. Уровень сжатия по сравнению с текстовыми форматами может достигать 10:1 и более.

Еще один немаловажный плюс – это поддержка сложных структур. Parquet нативно поддерживает вложенные структуры данных (arrays, maps, structs), что делает его идеальным для полуструктурированных данных, приходящих, например, из веб-аналитики или JSON-документов.

И, наконец, это строгая типизация и метаданные. Файлы Parquet содержат подробную метаинформацию о схеме данных, включая типы, что исключает ошибки интерпретации при чтении.

К рискам, сопряженным с использованием Parquet, в первую очередь стоит отнести неправильный выбор размера строковой группы (Row Group Size). Слишком большой размер может привести к неэффективному использованию памяти при чтении, а слишком маленький — увеличить накладные расходы на метаданные и снизить эффективность сжатия. Рекомендуемый размер — от 128 МБ до 1 ГБ.

Еще один потенциальный риск заключается в игнорировании схемы при записи. Запись данных без явного указания схемы может привести к неожиданным результатам, особенно при работе с вложенными структурами. Всегда явно определяйте схему при использовании API низкого уровня (например, в PyArrow).

Кроме того, могут возникнуть проблемы с параллельной записью. Попытка записывать в один файл Parquet из нескольких процессов одновременно приведет к его повреждению. Для многопроцессной записи необходимо использовать паттерн "один файл на процесс" или использовать специализированные системы вроде Apache Iceberg или Delta Lake, которые решают эту проблему.

 

Пример работы с Parquet:

# Запись DataFrame в Parquet с явными настройками
df = generate_users(100000)
df.to_parquet(
    path='../data/users.parquet',
    engine='pyarrow',  # Используем движок PyArrow для большей производительности
    compression='snappy',  # Быстрое сжатие, идеально для горячих данных
    index=False
)
# Чтение только необходимых колонок
df_filtered = pd.read_parquet(
    '../data/users.parquet',
    columns=['id', 'email', 'city']  # Считываются только эти 3 колонки
)
# Использование фильтров на уровне формата (pushdown predicates)
# Это мощнейшая оптимизация: фильтрация происходит во время чтения, и с диска считываются только соответствующие строки.
df_moscow = pd.read_parquet(
    '../data/users.parquet',
    filters=[('city', '=', 'Москва')]
)

 

CSV: универсальность ценой производительности

Comma-Separated Values — это в определенном смысле «пережиток эпохи», который, тем не менее, остается одним из самых распространенных форматов для обмена данными из-за своей простоты и человекочитаемости.

В-первых, это текстовый формат. Все данные, включая числа и даты, хранятся в виде строк, что приводит к значительным накладным расходам на хранение и необходимости парсинга при каждом чтении.

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

В – третьих, данный формат характеризуется избыточностью: названия колонок повторяются для каждой строки, что крайне неэффективно для больших файлов.

Основные риски использования данного формата связаны, в первую очередь, с инъекцией формул (Formula Injection). Значения, начинающиеся с =, +, -, @, могут интерпретироваться разными системами (например, Excel) как формулы, что представляет серьезную угрозу безопасности.

Существуют и определенные проблемы с кодировкой (Encoding Hell). Классическая ошибка — не указать кодировку при чтении/записи. Разные системы могут использовать разную кодировку по умолчанию (UTF-8, Windows-1251, CP866), что приводит к непонятным символам вместо текста.

Также потенциальный риск в себе несет несогласованное экранирование. Если данные содержат символ-разделитель (запятую), они должны быть заключены в кавычки. Однако если внутри поля тоже есть кавычки, их нужно экранировать.

 

Пример ра​боты с CSV:

df = generate_users(1000)
# Запись БЕЗ сжатия
df.to_csv(
    path_or_buf='../data/users.csv',
    index=False,
    sep=',',           # Явное указание разделителя
    encoding='utf-8-sig'  # Добавляет BOM для лучшей совместимости с Excel
)
# Запись СО сжатием - ОБЯЗАТЕЛЬНО для больших объемов
df.to_csv(
    path_or_buf='../data/users.csv.gz',
    compression='gzip',
    index=False
)
# Чтение с указанием типов и парсингом дат
df_from_csv = pd.read_csv(
    '../data/users.csv',
    dtype={'id': 'string', 'city': 'string'},  # Явное указание типов для строк
    parse_dates=['created_at', 'updated_at', 'birthday'], # Парсинг дат
    infer_datetime_format=True  # Ускоряет парсинг дат
)

 

JSON: гибкость для веба и потоковой передачи

JavaScript Object Notation идеален для передачи данных по сети и работы с веб-API благодаря своей гибкости и простой структуре.

Главное преимущество данного формата состоит в том, что его схема опциональна.  Гибкость схемы позволяет легко менять структуру данных, но отсутствие строгой схемы означает, что потребитель должен быть готов к любым неожиданностям в данных.

Еще одной важной особенностью является избыточность. Ключи повторяются для каждой записи, что приводит к значительному увеличению размера файла по сравнению с бинарными форматами.

Стоит упомянуть и об ориентации исключительно на строки. Чтение отдельных атрибутов без парсинга всего объекта невозможно.

Если говорить о потенциальных рисках, то здесь в первую очередь стоит сказать о раздувании размера (Data Bloat): Для больших datasets размер JSON становится непрактичным. Мы видели случаи, когда переход с JSON на Parquet для хранения одних и тех же логов сокращал объем хранилища на 90%.

Также существуют определенные проблемы с парсингом больших файлов. Попытка загрузить JSON-файл размером в несколько гигабайт в память целиком (json.load()) приведет к исчерпанию оперативной памяти. Необходимо использовать потоковые парсеры (ijson, jsonlines).

Кроме того, процесс парсинга JSON из текста в объекты в памяти вычислительно дорог и значительно замедляет загрузку больших объемов данных.

 

Пример работы с JSON:

# Запись в JSON. Обратите внимание на ориентацию.
df.to_json(
    path_or_buf='../data/users.json',
    orient='records',  # Записывает как список словарей [{...}, {...}]
    lines=True         # Формат JSON Lines: одна JSON-строка = одна запись. Лучше для потоковой обработки.
    force_ascii=False  # Корректное сохранение кириллицы
)
# Чтение JSON Lines
df_from_json = pd.read_json('../data/users.json', lines=True)
# Для больших файлов используйте потоковую обработку
import json
with open('../data/large_file.jsonl', 'r', encoding='utf-8') as f:
    for line in f:
        record = json.loads(line)
        # Обработка одной записи

 

Apache Avro: надежный контракт для потоковых данных

Apache Avro — это бинарный формат, который ставит схему данных во главу угла. Схема передается вместе с данными, что обеспечивает полную гарантию совместимости между производителем и потребителем. Это золотой стандарт для Kafka и потоковой передачи данных.

В первую очередь данный формат характеризуется максимально эффективным бинарным кодированием. Данные сериализуются в компактный бинарный формат согласно схеме, что обеспечивает малый размер и высокую скорость сериализации/десериализации.

Кроме того, Avro поддерживает совместимость схем вперед и назад через четко определенные правила (добавление полей с значениями по умолчанию, удаление полей и т.д.). Это критически важно для долгоживущих потоков данных.

Однако работа с Avro требует большего количества шагов по сравнению с другими форматами (необходимо определить схему, скомпилировать ее, если используете SpecificRecord, и только затем работать с данными. Стоит сказать и о сравнительно высоких операционных накладных расходах, связанных с необходимостью хранить и управлять схемами (часто для этого используется отдельный компонент — Schema Registry).

Кроме того, при работе с этим форматом, в случае, если данные не соответствуют заявленной схеме, может возникнуть ошибка сериализации. Это, с одной стороны, хорошо (гарантия качества), а с другой — требует надежного кода для производства данных.

 

Пример работы с Avro:

from avro import schema, datafile, io
import json
# 1. Определение схемы Avro (в коде или в отдельном .avsc файле)
avro_schema_str = """
{
  "type": "record",
  "name": "User",
  "fields": [
    {"name": "id", "type": "string"},
    {"name": "created_at", "type": "string"},  # В Avro 1.0 нет нативного типа timestamp, часто используют string или long
    {"name": "email", "type": "string"},
    {"name": "city", "type": "string"}
  ]
}
"""
parsed_schema = schema.parse(avro_schema_str)
# 2. Запись данных в файл Avro
df = generate_users(10)
# Преобразуем datetime в string для соответствия схеме
df['created_at'] = df['created_at'].astype(str)
with open('../data/users.avro', 'wb') as f:
    writer = datafile.DataFileWriter(f, io.DatumWriter(), parsed_schema, codec='deflate')
    for _, row in df.iterrows():
        writer.append(row.to_dict())
    writer.close()
# 3. Чтение данных из файла Avro
with open('../data/users.avro', 'rb') as f:
    reader = datafile.DataFileReader(f, io.DatumReader())
    for record in reader:
        print(record)
    reader.close()

 

Сравнительный анализ форматов данных: цифры и рекомендации

Давайте  оценим эффективность форматов на примере набора данных объемом в 1 миллион записей, сгенерированного нашим скриптом.

Формат

Размер на диске (МБ)

Время чтения (с)

Время записи (с)

Примечания

Parquet

~73 МБ

~1.2 с

~2.8 с

Snappy сжатие. Быстрое чтение выбранных колонок.

CSV

~205 МБ

~3.5 с

~1.5 с

Без сжатия. Медленное чтение из-за парсинга всех колонок и приведения типов.

CSV GZIP

~58 МБ

~4.1 с

~5.0 с

Высокий уровень сжатия, но очень медленное чтение и запись из-за затрат на сжатие/распаковку.

JSON

~382 МБ

~8.9 с

~3.1 с

Крайне высокий объем из-за повторения ключей. Очень медленный парсинг.

Avro

~65 МБ

~2.1 с

~3.5 с

Deflate сжатие. Размер сопоставим с Parquet, но чтение/запись медленнее из-за накладных расходов на работу со схемой и десериализацию.

 

В целом можно сказать, что для аналитических хранилищ и Data Lakes лучше всего использовать  Apache Parquet. Это безальтернативный выбор для большинства случаев. Он обеспечивает наилучшее соотношение скорости чтения, эффективности сжатия и совместимости с экосистемой Big Data (Spark, Trino, BigQuery).

Для потоковой передачи данных (Kafka) больше всего подойдет Apache Avro . Именно этот формат в состоянии обеспечить надежность, контроль схемы и эффективность.

Для обмена данными с внешними системами и ручной работы мы настоятельно рекомендуем использовать CSV. Его универсальность и человекочитаемость незаменимы. Всегда используйте сжатие (GZIP) для файлов больше нескольких мегабайт.

Для веб-API и конфигураций лучше всего использовать JSON. Его гибкость и удобство для разработчиков делают его идеальным для этих целей.

Помните, что не существует "лучшего формата". Есть формат, наиболее подходящий именно для Вашей конкретной задачи, объема данных, частоты access pattern и инфраструктуры. Наша компания предлагает услуги аудита вашей текущей data-архитектуры, проектирования оптимальных конвейеров данных и выбора технологического стека, который будет масштабироваться вместе с вашим бизнесом, а не тормозить его. Обращайтесь к нашим экспертам для проведения глубокого технического анализа и построения по-настоящему отказоустойчивой и эффективной data-платформы.

Узнать стоимость решенияЗапросить видео презентацию

← Предыдущая статья
Эволюция стратегий репликации данных: от ручных методов к автоматизированным платформам на базе Debezium и Apache Kafka
Следующая статья →
Построение высокопроизводительного хранилища данных на Greenplum с применением методологии Data Vault 2.0: от архитектурных принципов до промышленной эксплуатации

Решения

Анализировать ФинансыУвеличивайте ПродажиОптимальный Склад и ЛогистикаМаркетинговые Метрики

Клиенты
  • KazanExpress — торговая площадка, на которой представлены товары с бесплатной доставкой за один день в более, чем 70 городах России. Аналитическое решение на базе платформы данных Yandex Cloud позволило компании обеспечить демократизацию данных. Результат — принятие обоснованных решений на всех уровнях, увеличение лояльности партнеров и повышение прозрачности бизнеса.

    Мониторинг ключевых метрик в реальном времени минимизировал недополученную прибыль и обеспечил рост прибыльных направлений, а возможности геоаналитики сервиса Yandex DataLens помогли за короткое время проанализировать локации для открытия более 90 ПВЗ в 25 городах России и заложить основу для роста компании.

  • Русклимат
    Русклимат — международный торгово-производственный холдинг, концентрирующий опыт ведущих мировых производителей индустрии климата, мощный потенциал конструкторских бюро и лабораторий индустриального дизайна.
     
    Компания образована в 1996 году. За более чем двадцатилетнюю историю Русклимат прошел путь от локальной компании до мощной вертикально-интегрированной многопрофильной структуры.
     
  • СберКорус (Группа компаний Сбербанка) – это ИТ‑компания, ИТ‑интегратор, SaaS-провайдер. Является разработчиком цифровых сервисов и услуг для автоматизации широкого диапазона бизнес-процессов юридических лиц. В 2004 году компания стала первым в России оператором электронного документооборота, а в 2012 году вошла в экосистему Сбера. 

  • Розничный и интернет-магазин 12 Storeez один из лидеров на рынке женской одежды. С географией рынка не только на территории России, своя продукция представлена еще и в таких странах как Казахстан и Дубай.

  • Решения
    • Дистрибуция
    • Розничная торговля
    • Производство
    • Операторы связи
    • Страхование
    • Банки
    • Лизинг
    • Логистика
    • Нефтегазовый сектор
    • Медицина
    • Сеть ресторанов
    • E-Commerce
    • Энергетика
    • Фармацевтика
  • Услуги
    • Переход на отечественные BI и DWH
    • Консалтинг
    • Пилотный проект
    • Обучение и сертификация
    • Бесплатное обучение
    • Техническая поддержка
    • Технические задания
    • Сбор требований для проекта внедрения BI-системы
    • CI/CD для DWH
    • Аудит BI приложений
    • Выделенная команда
    • Настойка и поддержка баз данных
    • Разработка BI Стратегии
    • Styleguide для BI-системы
    • Как выбрать BI-систему
  • Платформы
    • FineBI
    • FineReport
    • FineDataLink
    • Коннекторы данных из 1С в BI
    • Airflow + NiFi
    • Visiology
    • Luxms BI
    • Modus BI
    • PIX BI
    • Arenadata
    • ClickHouse
    • Greenplum
    • Postgres Professional
    • Open-source BI: Superset/Metabase
    • Loginom
    • Yandex.DataLens
    • AI / Исскуственный интеллект
    • Optimacros
    • Шины данных
  • Курсы
    • Учебный курс Информационная грамотность
    • Учебный курс для бизнес-аналитиков
    • Учебный курс для системных аналитиков
    • Учебный курс по Data Governance
    • Учебный курс Как стать CDO
    • Учебный курс Современная архитектура хранилища данных
    • Учебный курс по Fine BI
    • Учебный курс по FineReport
    • Учебный курс по DWH
    • Учебный курс по Data Science (ML, AI)
    • Учебный курс по PostgreSQL
    • Учебный курс по Apache Airflow и NiFi
    • Учебный курс по Open-source BI
    • Учебный курс по ClickHouse
    • Учебный курс по DataLens
    • Учебный курс по Loginom
    • Учебный курс по Modus BI и ETL
    • Учебный курс по Visiology
    • Учебный курс по dbt
  • Функциональные решения
    • Создание Data Lake
    • Цифровая трансформация
    • Управление по KPI
    • Финансы
    • Продажи
    • Склад
    • HR
    • Маркетинг
    • Внутренний аудит
    • Категорийный менеджмент
    • S&OP и прогнозная аналитика
    • Геоаналитика
    • Цепочки поставок (SCM)
    • AutoML
    • Process Mining
    • Сквозная аналитика
  • Компания
    • О нас
    • Руководство
    • Новости
    • Клиенты
    • Скачать
    • Контакты
    • Политика конфиденциальности
RutubeVkontakteLinkedInYouTube
ООО "Би Ай Консалт",
ИНН: 7811437757,
ОГРН: 1097847154184
199178, Россия,
Санкт-Петербург,
6-ая линия В.О., Д. 63, 4 этаж
Тел: +7 (812) 334-08-01
Тел: +7 (499) 608-13-06
E-mail: info@biconsult.ru

 

 

 

 

 

×

Пользуясь сайтом, вы соглашаетесь с использованием cookies и политикой конфиденциальности.