Типы данных
В данном разделе описано, какие типы данных поддерживает YTsaurus, как они описываются в схеме и как они представляются в форматах.
Общая информация
YTsaurus поддерживает набор примитивных типов:
string
;integer
;boolean
;float
;double
;date
;datetime
;timestamp
;interval
.
А так же следующие композитные (сложные) типы:
optional
;list
;struct
;tuple
;variant
;tagged
.
Задать тип в схеме таблицы можно одним из двух способов:
- с помощью ключей
type
и (необязательно)required
— исторически первый способ, но так можно задать лишь примитивные или опциональные примитивные типы; - с помощью ключа
type_v3
.
В ключе type
всегда ожидается строка.
В ключе type_v3
ожидается либо строка для примитивных типов, либо YSON-словарь.
YSON-словарь всегда имеет ключ type_name
, в котором хранится имя типа.
Остальные ключи зависят от конкретного типа и описаны ниже.
Описание типов в схеме
Примитивные типы
Примитивные типы можно задать в схеме как с помощью ключа type
, так и с помощью ключа type_v3
.
Если примитивный тип T
задаётся с помощью type
, YTsaurus дополнительно проверит ключ required
в схеме:
required=%true
— колонка будет иметь строго заданный тип. ЗначениеNull
или отсутствие значения не допускаются;required=%false
— колонка будет иметь типoptional<T>
— будут допустимы все значения примитивного типа и значениеNull
.
В таблице перечислены поддерживаемые типы и их представление в ключах type
/type_v3
.
Описание | Представление в type |
Представление в type_v3 |
---|---|---|
целое число в диапазоне [-2^63, 2^63-1] |
int64 |
int64 |
целое число в диапазоне [-2^31, 2^31-1] |
int32 |
int32 |
целое число в диапазоне [-2^15, 2^15-1] |
int16 |
int16 |
целое число в диапазоне [-2^7, 2^7-1] |
int8 |
int8 |
целое число в диапазоне [0, 2^64-1] |
uint64 |
uint64 |
целое число в диапазоне [0, 2^32-1] |
uint32 |
uint32 |
целое число в диапазоне [0, 2^16-1] |
uint16 |
uint16 |
целое число в диапазоне [0, 2^8-1] |
uint8 |
uint8 |
вещественное 8-байтное число | double |
double |
вещественное 4-байтное число | float |
float |
стандартный булев тип true/false |
boolean |
bool (отличие от type ) |
произвольная последовательность байт | string |
string |
корректная UTF8 последовательность | utf8 |
utf8 |
строка, содержащая валидный JSON | json |
json |
UUID, произвольная последовательность 16 байт (хранится бинарное представление) | uuid |
uuid |
целое число в диапазоне [-53375809, 53375808 - 1] , выражает число дней, прошедших с unix-эпохи; выражаемый диапазон времени около 145'000 лет в прошлое и в будущее см. раздел про временные типы |
date32 |
date32 |
целое число в диапазоне [-53375809 * 86400, 53375808 * 86400 - 1] , выражает число секунд, прошедших с unix-эпохи; выражаемый диапазон времени около 145'000 лет в прошлое и в будущее см. раздел про временные типы |
datetime64 |
datetime64 |
целое число в диапазоне [-53375809 * 86400 * 10^6, 53375808 * 86400 * 10^6 - 1] , выражает число микросекунд, прошедших с unix-эпохи; выражаемый диапазон времени около 145'000 лет в прошлое и в будущее см. раздел про временные типы |
timestamp64 |
timestamp64 |
целое число в диапазоне [-9223339708800000000, 9223339708800000000] , выражает число микросекунд между двумя таймстемпами типа timestamp64 см. раздел про временные типы |
interval64 |
interval64 |
целое число в диапазоне [0, 49673 - 1] , выражает число дней, прошедших с unix-эпохи; выражаемый диапазон дат: [1970-01-01, 2105-12-31] см. раздел про временные типы |
date |
date |
целое число в диапазоне [0, 49673 * 86400 - 1] , выражает число секунд, прошедших с unix-эпохи; выражаемый диапазон времён: [1970-01-01T00:00:00Z, 2105-12-31T23:59:59Z] см. раздел про временные типы |
datetime |
datetime |
целое число в диапазоне [0, 49673 * 86400 * 10^6 - 1] , выражает число микросекунд, прошедших с unix-эпохи; выражаемый диапазон времён: [1970-01-01T00:00:00Z, 2105-12-31T23:59:59.999999Z] см. раздел про временные типы |
timestamp |
timestamp |
целое число в диапазоне [- 49673 * 86400 * 10^6 + 1, 49673 * 86400 * 10^6 - 1] , выражает число микросекунд между двумя таймстемпами типа timestamp см. раздел про временные типы |
interval |
interval |
произвольная YSON-структура, физически представляется последовательностью байт, не может иметь атрибут required=%true |
any |
yson (отличие от type ) |
системный сингулярный тип, возможно единственное значение null (заведение отдельной колонки с таким типом не имеет смысла, мы не ожидаем встретить этот тип в пользовательских таблицах, но тип полезен для интеграции с YQL) |
null |
null |
сингулярный тип, возможно единственное значение null , это тип, отличный от null (заведение отдельной колонки с таким типом не имеет особого смысла, мы не ожидаем встретить этот тип в пользовательских таблицах, но тип полезен для интеграции с YQL) |
void |
void |
Примеры в схеме:
type_v3=utf8
type_v3=bool
type_v3=yson
Временные типы
Есть два набора типов для работы со временем. Исторически, первые появившиеся в системе это date
, datetime
, timestamp
, interval
. Эти типы позволяют выражать времена от начала 1970 года до конца 2105 года. Позже появились типы date32
, datetime64
, timestamp64
и interval64
. Эти типы позволяют выражать времена в более широком диапазоне, около 145'000 в прошлое и столько же в будущее. Предпочтительнее использовать последние типы, у них более широкий диапазон значений.
Все времена подразумевают использование григорианского календаря. При работе с моментами времени в далёком прошлом, стоит иметь ввиду, что YT никак не учитывает переход на григорианский каледнарь, который происходил в разных государствах в разное время. YT считает, что григорианский календарь использовался всегда.
Десятичное число / decimal
Значения типа decimal(p, s)
— вещественные числа с указанной точностью.
Чтобы задать этот тип в схеме, укажите следующие ключи:
type_name
- значениеdecimal
;precision
- общее число десятичных цифр в представлении числа,precision
должен находиться в диапазоне[1, 35]
;scale
- число десятичных цифр в представлении числа, которые идут после десятичной точки,scale
должно находится в диапазоне[0, precision]
.
Пример в схеме:
type_v3={
type_name=decimal;
precision=10;
scale=2;
}
Значения 3.14
, -2.71
, 9.99
могут иметь тип decimal(3, 2)
(precision=3
, scale=2
).
Тип поддерживает несколько специальных значений: nan
, +inf
, -inf
.
Описание бинарного представления decimal
Для decimal
-чисел есть специальное бинарное представление,
которое по умолчанию используется во многих форматах, например, yson
.
В этом представлении значения типов decimal(p, s)
представляются бинарными строками. Длина бинарной строки
зависит от precision
.
Precision | Число бит в представлении | Число байт в представлении |
---|---|---|
1-9 | 32 | 4 |
10-18 | 64 | 8 |
19-38 | 128 | 16 |
39-76 | 256 | 32 |
Чтобы получить бинарное представление decimal
-числа, нужно сделать следующие шаги. Шаги будут проиллюстрированы значениями 3.1415
, -2.7182
типа decimal(5, 4)
.
- Возьмите целое число, образованное десятичными цифрами значения. Число бит выбирается из
precision
по таблице выше. В данном примере — 32-битные числа31415
,-27182
. - Запишите число в big-endian представлении. В данном примере — строки
\x00\x00\x7A\xB7
,\xFF\xFF\x95\xD2
. - Инвертируйте старший бит. В данном примере — строки
\x80\x00\7A\xB7
,\x7F\xFF\x95\xD2
.
Целочисленные представления специальных значений nan
, +inf
, -inf
для первого шага представлены в таблице ниже:
Специальное значение | Целочисленное представление |
---|---|
nan |
INT_MAX |
+inf |
INT_MAX - 1 |
-inf |
- INT_MAX + 1 |
Обратите внимание
На текущий момент при работе с YQL поддерживаются только decimal
со значением precision
не более 35.
Опциональный тип / optional
Тип optional<T>
означает, что значение может иметь тип T
или отсутствовать.
Обратите внимание
Каждое применение optional
для типа добавляет новые значения.
Например, тип optional<optional<bool>>
может иметь следующие значения:
- внешний
optional
не заполнен; - внешний
optional
заполнен, внутренний не заполнен; - все
optional
заполнены, значениеtrue
илиfalse
.
Старые колонки, в которых заданы атрибуты type=T;required=false
, соответствуют типу optional<T>
, заданному через type_v3
.
Чтобы задать тип optional
, укажите ключи:
type_name
— значениеoptional
;item
— описание типа элемента.
Примеры в схеме:
type_v3={
type_name=optional;
item=string;
}
type_v3={
type_name=optional;
item={
type_name=optional;
item=bool;
}
}
Список / list
Значения типа list<T>
— списки элементов типа T
.
Чтобы задать тип в схеме, укажите ключи:
type_name
— значениеlist
;item
— описание типа элемента.
Примеры в схеме:
type_v3={
type_name=list;
item=string;
}
type_v3={
type_name=list;
item={
type_name=list;
item=double;
}
}
Структура / struct
Набор именованных полей с указанными типами значений.
Чтобы задать этот тип в схеме, укажите ключи:
type_name
— значениеstruct
;members
— список словарей с ключами:name
— имя поля, должно быть непустой utf8-строкой;type
— тип поля.
Примеры в схеме:
type_v3={
type_name=struct;
members=[
{
name=foo;
type=int32;
};
{
name=bar;
type={
type_name=optional;
item=string;
}
};
]
}
Кортеж / tuple
Набор безымянных полей с фиксированными типами.
Чтобы задать этот тип, в схеме нужно указать следующие ключи:
type_name
— значениеtuple
;elements
— список словарей с ключами:type
— тип элемента.
Пример в схеме:
type_v3={
type_name=tuple;
elements=[
{
type=double;
};
{
type=double;
};
]
}
Вариант / variant
Вариант — строго одно значение из фиксированного набора типов.
Вариант бывает двух типов:
- Вариант над структурой. Каждый тип имеет имя (как в структуре) и каждое значение варианта маркировано именем соответствующего элемента варианта;
- Вариант над кортежем. тогда все элементы безымянные и каждое значение маркируется индексом.
Чтобы задать этот тип, в схеме укажите ключи:
type_name
— значениеvariant
;elements
илиmembers
(но не оба), ключи имеют структуру аналогичную этим ключам вtuple
/struct
:
elements
— для варианта с безымянными элементами, сам ключ содержит список словарей с ключами:type
— тип элемента;
members
— для варианта с именованными элементами, сам ключ содержит список словарей с ключами:name
— имя элемента, должно быть непустой utf8-строкой;type
— описание типа элемента.
Пример в схеме:
type_v3={
type_name=variant;
members=[
{
name=int_field;
type=int64;
};
{
name=string_field;
type=string;
};
]
}
type_v3={
type_name=variant;
elements=[
{
type=int32;
};
{
type=string;
};
{
type=double;
};
]
}
Словарь / dict
Словарь — это последовательность пар ключ-значение.
YTsaurus не проверяет уникальность ключей или их порядок.
Однако большая часть клиентов при обработке будет загружать данные в реальный словарь, и значения для повторяющихся ключей будут утеряны.
Чтобы задать этот тип, в схеме укажите ключи:
type_name
— значениеdict
;key
— описание типа ключа;value
— описание типа значения.
Пример в схеме:
type_v3={
type_name=dict;
key=int64;
value={
type_name=optional;
item=string;
};
}
Тегированное значение / tagged
Тип tagged
позволяет аннотировать другие типы строкой. Значением типа tagged<TAG_NAME,T>
может быть любое значение типа T
,
однако сами типы будут считаться различными в тех местах, где YTsaurus сравнивает схемы. Например, когда проверяется возможность объединить две таблицы в одну.
Чтобы задать этот тип, в схеме укажите ключи:
type_name
— значениеtagged
;tag
— имя тега, должно быть непустой utf8-строкой;item
— описание типа элемента.
—
Пример в схеме:
type_v3={
type_name=tagged;
tag="image/svg";
item="string";
}
Представление сложных типов в форматах
Для чтения и записи таблиц используются форматы.
Не все форматы поддерживают сложные данные, некоторые из них, например, dsv / schemaful_dsv, будут возвращать ошибку при попытке прочитать сложное значение. Например, Values of type "any" are not supported by the chosen format
.
YSON
Существует два YSON представления сложных типов. Различаются представления типов struct
и variant
:
представление по умолчанию более удобно в использовании,
альтернативное представление несколько эффективнее в хранении и обработке.
Представления переключаются флагом complex_type_mode
. Возможные значения: named
/ positional
.
Ниже описаны представления типов. Если не указано иное, представление типа не зависит от настройки complex_type_mode
.
Есть два представления для типа dict
со строковыми ключами: по умолчанию используется positional
представление в виде списка (так как данные хранятся в YTsaurus). Для удобства восприятия можно включить режим named
с помощью флага string_keyed_dict_mode
.
Примитивные типы
Примитивные типы представляются прямолинейно одним YSON-значением.
В таблице приведено соответствие примитивных типов и YSON-типов.
type / type_v3 |
Представление в yson |
---|---|
int64 |
знаковое число |
int32 |
знаковое число |
int16 |
знаковое число |
int8 |
знаковое число |
uint64 |
беззнаковое число |
uint32 |
беззнаковое число |
uint16 |
беззнаковое число |
uint8 |
беззнаковое число |
double |
число с плавающей точкой |
boolean / bool |
булево значение |
string |
строка |
utf8 |
строка |
date |
беззнаковое число, см ниже |
datetime |
беззнаковое число, см ниже |
timestamp |
беззнаковое число, см ниже |
interval |
знаковое число |
uuid |
строка с бинарными данными, см ниже |
any / yson |
зависит от значения |
null |
# |
void |
# |
Временные типы
В yson-формате есть опция time_mode
, которая управляет представлением типов date
, datetime
, timestamp
. Ее возможные значения такие:
binary
(по-умолчанию) — используется представление в виде беззнакового числа, обозначающего число дней / секунд / миллисекунд с начала unix эпохи.text
— используется строковое представление, примеры представленияdate
,datetime
,timestamp
соответственно такие:
2022-01-02
,2022-01-02T03:04:05Z
,2022-01-02T03:04:05.123456Z
.
UUID
В yson-формате есть опция uuid_mode
, которая управляет представлением типа uuid
. Её возможные значения:
binary
(по умолчанию) — используется бинарное представление из 16 байт.text_yt
— используется строковое представление, в формате YTsaurus из 4 групп, например61626364-65666768-696a6b6c-6d6e6f70
;text_yql
— используется строковое представление, в формате YQL из 5 групп более похожим на представление RFC, например64636261-6665-6867-696a-6b6c6d6e6f70
.
Decimal
В YSON формате есть опция decimal_mode
, которая управляет представлением типа decimal
. Ее возможные значения:
binary
(по-умолчанию) — кодируется бинарной строкой с бинарным представлениемdecimal
-числа.text
— используется текстовое представлениеdecimal
-числа.
Optional
Представление типа optional
зависит от его внутреннего типа.
Это необходимо для обратной совместимости с колонками, для которых проставлено required=%false
.
Если T
— произвольный тип, который не является optional
, то optional<T>
представляется следующим образом:
Null
значениеoptional
представляется#
;- в противном случае используется обычное представление значения типа
T
.
Если T
— тип, который является optional
, то optional<T>
представляется следующим образом:
Null
значение внешнегоoptional
представляется#
;- в противном случае используется представление
[ v ]
(yson-список длины 1), гдеv
— YSON-представление значения типаT
.
Примеры значений, тип optional<int64>
:
#
-42
Примеры значений, тип optional<optional<int64>>
:
#
[ # ]
[ -42 ]
List
Тип list<T>
кодируется YSON-списком, элементы которого представляют собой кодированное представление элементов типа T
.
Примеры значений, тип list<int64>
:
[]
[42; -1;]
Struct
Представление структуры зависит от значения флага complex_type_mode
.
Именованное представление (по умолчанию)
Описываемое представление для случая,
когда опция YSON формата complex_type_mode
не выставлена или выставлено значение complex_type_mode=named
.
Структура представлена YSON-словарём, где ключи — имена полей, а значения — их содержимое.
Примеры значений, тип struct<Foo:int64;Bar:optional<utf8>>
:
{Foo=42;Bar=#;}
{Foo=-5;Bar="minus five";}
Позиционное представление
В случае, если для YSON-формата выставлена опция complex_type_mode=positional
, используется другое представление.
Структура кодируется YSON-списком, где на i-й позиции стоит YSON-представление i-го поля структуры.
Длина списка может быть меньше, чем число полей в структуре, тогда оставшиеся типы должны иметь тип optional<T>
,
и считается, что поля имеют пустое optional
значение.
Примеры значений, тип struct<Foo:int64;Bar:optional<utf8>>
:
[42; #;]
[42]
[-5;"minus five";]
Tuple
Тип tuple
кодируется YSON-списком фиксированной длины. На i-м месте стоит кодированное значение i-го поля.
Примеры значений, тип tuple<int64;optional<utf8>>
:
[42; #;]
[-5;"minus five";]
Variant
Неименованный variant
Неименованный вариант представлен YSON-списком длины 2 из следующих элементов:
- номер альтернативы (индексация с 0);
- кодированное значение соответствующей альтернативы.
Примеры значений, тип variant<int64;optional<utf8>>
:
[0; 42]
[1; #]
[1; "foo bar";]
Именованный вариант variant
Именованное представление (по умолчанию)
Описываемое представление для случая, когда опция YSON-формата complex_type_mode
не выставлена или выставлена в значение complex_type_mode=named
.
Именованный вариант представляется YSON-списком длины 2 из следующих элементов:
- имя альтернативы;
- кодированное значение соответствующей альтернативы.
Примеры значений, тип `variant<Foo:int64;Bar:optional
[Foo; 42]
[Bar; #]
[Bar; "foo bar";]
Позиционное представление
Если для формата выставлена опция complex_type_mode=positional
.
Именованный вариант представлен YSON-списком длины 2 из следующих элементов:
- индекс альтернативы;
- кодированное значение соответствующей альтернативы.
Примеры значений, тип variant<Foo:int64;Bar:optional<utf8>>
:
[Foo; 42]
[Bar; #]
[Bar; "foo bar";]
Dict
Тип dict
по умолчанию представлен YSON-списком, где каждый элемент — YSON-список из двух элементов: ключ и значение.
Примеры значений типа dict<int32;string>
:
[[1;"one"];[4;"four"]]
[]
dict
может быть представлен YSON-словарём, однако YSON-словарь поддерживает только строки в качестве ключей, а dict
поддерживает и другие ключи.
Dict with string keys
Представление словаря со строковыми ключами зависит от значения флага string_keyed_dict_mode
.
Позиционное представление (по умолчанию)
Описываемое представление для случая, когда опция YSON формата string_keyed_dict_mode
не выставлена или выставлена в значение string_keyed_dict_mode=positional
.
См. выше
Примеры значений типа dict<string;int32>
:
[["one";1];["four";4]]
Именованное представление
Если для YSON-формата выставлена опция string_keyed_dict_mode=named
, используется другое представление.
dict
кодируется YSON-словарём.
Примеры значений типа dict<string;int32>
:
{one=1; four=4}
Tagged
Тип tagged
не меняет YSON представление его элемента.