Форматы данных и алгоритмы сжатия

В данном разделе описываются поддерживаемые в YDB форматы данных, хранимых в S3, поддерживаемые алгоритмы сжатия и список поддерживаемых YQL типов для каждого формата данных.

Поддерживаемые форматы данных

Список поддерживаемых в YDB форматов данных приведен в таблице ниже.

Формат Чтение Запись
csv_with_names
tsv_with_names
json_list
json_each_row
json_as_string
parquet
raw

Формат csv_with_names

Данный формат основан на формате CSV. Данные размещены в колонках, разделены запятыми, в первой строке файла находятся имена колонок.

Пример данных:

Year,Manufacturer,Model,Price
1997,Man_1,Model_1,3000.00
1999,Man_2,Model_2,4900.00
Пример запроса
SELECT
    *
FROM external_source.path
WITH
(
    FORMAT = "csv_with_names",
    SCHEMA =
    (
        Year Int32,
        Manufacturer Utf8,
        Model Utf8,
        Price Double
    )
)

Результат выполнения запроса:

# Manufacturer Model Price Year
1 Man_1 Model_1 3000 1997
2 Man_2 Model_2 4900 1999

Формат tsv_with_names

Данный формат основан на формате TSV. Данные размещены в колонках, разделены символами табуляции (код 0x9), в первой строке файла находятся имена колонок.

Пример данных:

Year    Manufacturer    Model   Price
1997    Man_1   Model_1    3000.00
1999    Man_2   Model_2    4900.00
Пример запроса
SELECT
    *
FROM external_source.path
WITH
(
    FORMAT = "tsv_with_names",
    SCHEMA =
    (
        Year Int32,
        Manufacturer Utf8,
        Model Utf8,
        Price Double
    )
)

Результат выполнения запроса:

# Manufacturer Model Price Year
1 Man_1 Model_1 3000 1997
2 Man_2 Model_2 4900 1999

Формат json_list

Данный формат основан на JSON-представлении данных. В этом формате внутри каждого файла должен находиться объект в корректном JSON-представлении.

Пример корректных данных (данные представлены в виде списка объектов JSON):

[
    { "Year": 1997, "Manufacturer": "Man_1", "Model": "Model_1", "Price": 3000.0 },
    { "Year": 1999, "Manufacturer": "Man_2", "Model": "Model_2", "Price": 4900.00 }
]

Пример НЕкорректных данных (на каждой отдельной строке находится отдельный объект в формате JSON, но эти объекты не объединены в список):

{ "Year": 1997, "Manufacturer": "Man_1", "Model": "Model_1", "Price": 3000.0 }
{ "Year": 1999, "Manufacturer": "Man_2", "Model": "Model_2", "Price": 4900.00 }
Пример запроса
SELECT
    *
FROM external_source.path
WITH
(
    FORMAT = "json_list",
    SCHEMA =
    (
        Year Int32,
        Manufacturer Utf8,
        Model Utf8,
        Price Double
    )
)

Результат выполнения запроса:

# Manufacturer Model Price Year
1 Man_1 Model_1 3000 1997
2 Man_2 Model_2 4900 1999

Формат json_each_row

Данный формат основан на JSON-представлении данных. В этом формате внутри каждого файла на каждой отдельной строке файла должен находиться объект в корректном JSON-представлении, но эти объекты не объединены в JSON-список. Такой формат используется при передаче данных через потоковые системы, например, Apache Kafka или Топики YDB.

Пример корректных данных (на каждой отдельной строке находится отдельный объект в формате JSON, но эти объекты не объединены в список):

{ "Year": 1997, "Manufacturer": "Man_1", "Model": "Model_1", "Price": 3000.0 },
{ "Year": 1999, "Manufacturer": "Man_2", "Model": "Model_2", "Price": 4900.00 }
Пример запроса
SELECT
    *
FROM external_source.path
WITH
(
    FORMAT = "json_each_row",
    SCHEMA =
    (
        Year Int32,
        Manufacturer Utf8,
        Model Utf8,
        Price Double
    )
)

Результат выполнения запроса:

# Manufacturer Model Price Year
1 Man_1 Model_1 3000 1997
2 Man_2 Model_2 4900 1999

Формат json_as_string

Данный формат основан на JSON-представлении данных. Формат json_as_string не разбивает входной JSON-документ на поля, а представляет каждую строку файла в виде одного объекта JSON (или одной строки). Такой формат удобен, если список полей не одинаков во всех строках, а может изменяться.

В этом формате внутри каждого файла должен находиться:

  • объект в корректном JSON-представлении в каждой отдельной строке файла;
  • объекты в корректном JSON-представлении, объединенные в список.

Пример корректных данных (данные представлены в виде списка объектов JSON):

{ "Year": 1997, "Attrs": { "Manufacturer": "Man_1", "Model": "Model_1" }, "Price": 3000.0 }
{ "Year": 1999, "Attrs": { "Manufacturer": "Man_2", "Model": "Model_2" }, "Price": 4900.00 }

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

Пример запроса
SELECT
    CAST(JSON_VALUE(Data, "$.Year") AS Int32) AS Year,
    JSON_VALUE(Data, "$.Attrs.Manufacturer") AS Manufacturer,
    JSON_VALUE(Data, "$.Attrs.Model") AS Model,
    CAST(JSON_VALUE(Data, "$.Price") AS Double) AS Price
FROM external_source.path
WITH
(
    FORMAT = "json_as_string",
    SCHEMA =
    (
        Data Json
    )
)

Результат выполнения запроса:

# Manufacturer Model Price Year
1 Man_1 Model_1 3000 1997
2 Man_2 Model_2 4900 1999

Формат parquet

Данный формат позволяет считывать содержимое файлов в формате Apache Parquet.

Поддерживаемые алгоритмы сжатия данных внутри файлов Parquet для чтения из S3:

  • Без сжатия
  • SNAPPY
  • GZIP
  • BROTLI
  • LZ4
  • ZSTD
  • LZ4_RAW

Примечание

Запись в формате Parquet будет производится с использованием алгоритма сжатия Snappy.

Пример запроса
SELECT
    *
FROM external_source.path
WITH
(
    FORMAT = "parquet",
    SCHEMA =
    (
        Year Int32,
        Manufacturer Utf8,
        Model Utf8,
        Price Double
    )
)

Результат выполнения запроса:

# Manufacturer Model Price Year
1 Man_1 Model_1 3000 1997
2 Man_2 Model_2 4900 1999

Формат raw

Данный формат позволяет считывать содержимое файлов как есть, в "сыром" виде. Считанные таким образом данные можно обработать средствами YQL, разделив на строки и столбцы.

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

Примечание

Размер каждого из считываемых файлов в формате raw не может превышать общего ограничения на потребление памяти одним запросом в YDB.

Пример запроса

Для парсинга следующих данных, где строки разделены точкой с запятой, а значения запятой:

1997,Man_1,Model_1,3000.00;
1999,Man_2,Model_2,4900.00;

Можно использовать запрос:

$input = SELECT
    String::SplitToList(        -- разделение каждой строки по ','
        String::Strip(RowData), -- удаление всех пробельных символов из начала и конца строк
        ","
    ) AS Row
FROM external_source.path
WITH
(
    FORMAT = "raw",
    SCHEMA =
    (
        FileData Utf8
    )
)
FLATTEN LIST BY (String::SplitToList(FileData, ";", TRUE AS SkipEmpty) AS RowData); -- разделение файла по ';'

SELECT -- Получение нужных колонок
    CAST(Row[0] AS Int32) AS Year,
    Row[1] AS Manufacturer,
    Row[2] AS Model,
    CAST(Row[3] AS Double) AS Price
FROM $input

Результат выполнения запроса:

# Manufacturer Model Price Year
1 Man_1 Model_1 3000 1997
2 Man_2 Model_2 4900 1999

Поддерживаемые алгоритмы сжатия

Использование алгоритмов сжатия зависит от форматов файлов. Для всех форматов файлов за исключением Parquet возможно использование следующих алгоритмов сжатия:

Алгоритм Название в YDB Чтение Запись
Gzip gzip
Zstd zstd
LZ4 lz4
Brotli brotli
Bzip2 bzip2
Xz xz

Для формата файлов Parquet поддерживаются собственные внутренние алгоритмы сжатия:

Формат сжатия Чтение Запись
Без сжатия
Snappy
Gzip
Brotli
LZ4
Zstd
LZ4_RAW

В YDB не поддерживается работа со сжатыми "снаружи" parquet-файлами, например, с файлами вида <myfile>.parquet.gz или аналогичными. Все файлы в формате Parquet должны быть без внешнего сжатия.

Поддерживаемые типы данных

Таблица всех поддерживаемых типов при чтении из S3 в схеме запроса:

Тип csv_with_names tsv_with_names json_list json_each_row json_as_string parquet raw
Bool,
Int8, Int16, Int32, Int64,
Uint8, Uint16, Uint32, Uint64,
Float, Double
DyNumber
String, Utf8, Json
JsonDocument
Yson
Uuid
Date, Datetime, Timestamp,
TzDate, TzDateTime, TzTimestamp
Interval
Date32, Datetime64, Timestamp64,
Interval64,
TzDate32, TzDateTime64, TzTimestamp64
Optional<T>

Таблица всех поддерживаемых типов при записи в S3:

Тип csv_with_names tsv_with_names json_list json_each_row parquet raw
Bool,
Int8, Int16, Int32, Int64,
Uint8, Uint16, Uint32, Uint64,
Float, Double
DyNumber
String, Utf8, Json
JsonDocument
Yson
Uuid
Date, Datetime, Timestamp,
TzDate, TzDateTime, TzTimestamp
Interval
Date32, Datetime64, Timestamp64,
Interval64,
TzDate32, TzDateTime64, TzTimestamp64
Optional<T>

Для всех форматов чтения из S3 и записи в S3, кроме json_list, разрешено использовать тип Optional<T> только в том случае, если Tпримитивный YQL тип. Подробнее об опциональных типах см. в статье Типы данных, допускающие значение NULL.