Схема данных
Общее описание
Схема таблицы описывает известные колонки и их типы.
Схему можно прочитать из системного атрибута @schema
, который есть у каждой таблицы.
Чтобы задать схему, установите этот атрибут при создании таблицы.
Чтобы изменить схему у существующей таблицы используйте команду alter_table
.
Подробнее можно прочитать в разделе Примеры работы со схемой.
Тип TableSchema
— это список элементов ColumnSchema
.
Каждый такой элемент — словарь с фиксированной структурой:
Имя | Тип | Описание | Обязательный |
---|---|---|---|
name |
string |
Имя колонки. | Да |
type |
string |
Тип элементов колонки. | Да, если не указан type_v3 |
type_v3 |
any |
Альтернативное представление типа. Это поле позволяет задавать колонки со сложными типами. | Да, если не указан type |
sort_order |
string |
Порядок сортировки колонки, допускается либо отсутствующее значение, либо значение ascending . Если значение выставлено, то колонка является ключевой. |
Нет |
lock |
string |
Имя блокировки. Только для неключевых колонок. | Нет |
expression |
string |
Выражение, определяющее значение поля вычислимой колонки. Только для ключевых колонок. Подробнее можно прочитать в разделе Шардирование. | Нет |
aggregate |
string |
Имя агрегирующей функции. Только для неключевых колонок. | Нет |
required |
boolean |
Если выставлено в %true , то значение в колонке не должно быть null . По умолчанию required=%false . Колонка типа any не может быть required=%true . |
Нет |
group |
string |
Если две колонки имеют одинаковое имя группы, то данные этих колонок попадут в одни и те же блоки. Менять атрибут group можно в любой момент с помощью команды alter-table , изменения будут применяться к новым чанкам. |
Нет |
Свойства схемы:
- имя колонки должно быть непустой строкой. Максимальная длина — 256 символов;
- имя колонки не может начинаться с системного префикса
@
; - имена колонок не могут повторяться в пределах таблицы;
- ключевые колонки должны образовывать префикс схемы;
- все ключевые колонки должны быть указаны в схеме;
- поддерживается до 32 000 колонок, но рекомендуется ограничиться единицами тысяч;
- у колонки всегда должен быть явно указан тип: в атрибуте
type
илиtype_v3
; - при чтении схемы всегда возвращаются оба атрибута: и
type
, иtype_v3
независимо от того, как схема была создана; - вычислимые колонки могут быть только ключевыми. Вычислимые колонки могут зависеть только от ключевых невычислимых колонок.
Атрибуты схемы:
strict
типаboolean
. По умолчаниюtrue
. Если таблица строгая, то есть атрибут имеет значениеtrue
, то в таблицу нельзя записать данные в отсутствующую в схеме колонку. В противном случае допускается запись в отсутствующую колонку, которая автоматически появится, но только у новой строки.unique_keys
типаboolean
. По умолчаниюfalse
. Если атрибут имеет значениеtrue
и таблица сортирована, то все ключи в таблице должны быть уникальны.
Поддерживаемые типы колонок
YTsaurus поддерживает типы колонок, описанные в разделе Типы данных.
Среди них есть как примитивные, так и композитные типы.
Значения в ячейках таблицы всегда имеют тот тип, который указан в схеме.
Задать тип в схеме таблицы можно одним из способов:
- с помощью ключей
type
и (необязательно)required
можно задать только примитивные или опциональные примитивные типы; - с помощью ключа
type_v3
.
В ключе type
ожидается строка.
В ключе type_v3
ожидается либо строка (для примитивных типов), либо yson-словарь.
Yson-словарь всегда имеет ключ type_name
, в котором хранится имя типа.
Остальные ключи зависят от конкретного типа и описаны на странице Типы данных.
Для примитивных типов кроме any
/ yson
действуют стандартные отношения порядка.
Отношения порядка действуют так же для типов optional<T>
, где T
— это примитивный сравнимый тип.
Гарантируется, что отсутствующие значения — значения типа null
— меньше любого значения любого типа.
Поддерживается возможность сравнивать элементы сравнимых типов.
Сравнение сначала выполняется по типу, а затем, при совпадении типов, происходит сравнение значений.
Порядок между различными типами не специфицирован. Например, не имеет смысла сравнивать 100
и 3.14
, так как результат не специфицирован.
Примеры схем
<strict=%false>[]
key1; key2
.<strict=%false>[
{
name = "key1";
type = "any";
sort_order = "ascending"
type_v3= {
type_name=optional;
item=yson;
};
};{
name = "key2";
type = "any";
sort_order = "ascending"
type_v3= {
type_name=optional;
item=yson;
};
}
]
[
{
name = "key";
type = "string";
sort_order = "ascending"
};{
name = "subkey";
type = "string";
sort_order = "ascending"
};{
name = "value";
type = "string"
}
]
[
{
name = "key";
type = "string";
sort_order = "ascending";
group = "g1"
};{
name = "subkey";
type = "string";
sort_order = "ascending";
group = "g1"
};{
name = "value";
type = "string";
sort_order = "ascending";
}
]
<strict=%false>[
{
"name" = "id";
"type" = "int64";
};{
"name" = "class";
"type" = "int64";
};{
"name" = "uid";
"type" = "string";
};{
"name" = "ip";
"type" = "int64";
};{
"name" = "iso_eventtime";
"type" = "string";
};{
"name" = "error";
"type" = "string"
};{
"name" = "ip6";
"type" = "string"
};{
"name" = "port";
"type" = "int64"
};{
"name" = "comment";
"type" = "string"
}
]
Слабая и сильная схема
У таблицы существует атрибут schema_mode
, который определяет источник происхождения схемы.
Если схема не была установлена пользователем явно, атрибут @schema_mode
будет иметь значение weak
. Это означает, что схема таблицы создана автоматически и нужна только для разметки ключевых колонок.
Такая схема автоматически изменяется, если таблица теряет свойство сортированности или меняет набор ключевых колонок.
Например, запись с флагом <append=%true>
в сортированную таблицу без указания атрибута sorted_by
приводит к тому, что таблица теряет свойство сортированности, а значит, меняется ее схема — как минимум, атрибут sort_order
.
Если схема таблицы установлена пользователем явно, то @schema_mode == strong
. Схема такой таблицы сохраняется и проверяется при записи, как в режиме append
, так и в режиме overwrite
. Неявные преобразования с сильной схемой невозможны.
# Создать таблицу без схемы
$ yt --proxy <cluster-name> create table //tmp/table_1
213c-a01da-3fc0191-54a9a802
$ yt --proxy <cluster-name> get //tmp/table_1/@schema_mode
"weak"
$ yt --proxy <cluster-name> get //tmp/table_1/@schema
<
"unique_keys" = %false;
"strict" = %false;
> []
# Создать таблицу с явным указанием схемы
$ yt --proxy <cluster-name> create table //tmp/table_2 --attributes '{schema = [{name = a; type = int64}; {name = b; type = string}]}'
213c-b75ef-3fc0191-1e85fe66
$ yt --proxy <cluster-name> get //tmp/table_2/@schema_mode
"strong"
$ yt --proxy <cluster-name> get //tmp/table_2/@schema
<
"unique_keys" = %false;
"strict" = %true;
> [
{
"name" = "a";
"type" = "int64";
};
{
"name" = "b";
"type" = "string";
};
]
Преимущества строгой схематизации
- Производительность:
- Если дополнительно включить поколоночный формат хранения чанков
optimize_for = scan
, то данные будут храниться компактнее, а чтение подмножества колонок будет быстрее. - Некоторые табличные ридеры могут работать быстрее для таблиц со схемой.
- Если дополнительно включить поколоночный формат хранения чанков
- Удобство и более широкие возможности:
- В YQL удобнее работать со схематизированными таблицами;
- В CHYT нельзя работать с несхематизированными данными.
Наследование схемы в системных операциях
Системные операции Sort, Erase, Merge и Remote copy могут самостоятельно выводить схему выходной таблицы. Правила вывода схемы для операций регулируются опцией спецификации schema_inference_mode = (auto|from_input|from_output)
. Примеры использования опций можно найти в разделе Примеры.
Ordered merge, Erase
Опция | Описание |
---|---|
from_input |
Схемы всех таблиц должны совпадать с точностью до атрибута sort_order и порядка колонок. Тогда схема выходной таблицы совпадает со схемой входных таблиц. Если входная таблица одна, сортированность сохраняется. Если входные таблицы имели сильную схему, то и выходная таблица будет иметь сильную схему. |
from_output |
Используется схема выходной таблицы, данные валидируются относительно этой схемы. |
auto |
При наличии сильной схемы у выходной таблицы проверяется, что она совместима по типам со схемой всех сильно схематизированных входных таблиц. При наличии слабой схемы у выходной таблицы, схема выводится из схем входных таблиц аналогично опции from_input . |
Unordered merge
Опция | Описание |
---|---|
from_input |
Должны совпадать количество и типы колонок, тогда схема выходной таблицы совпадает со схемой входных таблиц за исключением сортированности. Если входные таблицы имели сильную схему, то и выходная таблица будет иметь сильную схему. |
from_output |
Используется схема выходной таблицы, данные валидируются относительно этой схемы. |
auto |
При наличии сильной схемы у выходной таблицы проверяется, что она совместима по типам со схемой всех сильно схематизированных входных таблиц. При наличии слабой схемы у выходной таблицы, схема выводится из схем входных таблиц (аналогично опции from_input ). |
Sorted merge
Опция | Описание |
---|---|
from_input |
Должны совпадать количество и типы колонок, тогда схема выходной таблицы совпадает со схемой входных таблиц, ключевые колонки проставляются в соответствии с параметром merge_by спецификации. Если входные таблицы имели сильную схему, то и выходная таблица будет иметь сильную схему. |
from_output |
Проверяется что ключевые колонки выходной таблицы совпадают с ключевыми колонками merge_by из спецификации. |
auto |
При наличии сильной схемы у выходной таблицы проверяется, что она совместима по типам со схемой всех сильно схематизированных входных таблиц. Проверяется соответствие ключевых колонок параметру merge_by . При наличии слабой схемы у выходной таблицы, схема выводится из схем входных таблиц аналогично опции from_input . |
Sort
Sort
— единственная операция которая может поменять сильную схему таблицы. Меняется порядок колонок: ключевые колонки переставляются в начало и проставляется атрибут sort_order
. Это обусловлено распространенным сценарием замены таблицы на ее сортированную копию.
Опция | Описание |
---|---|
from_input |
Если все входные таблицы имеют сильные схемы, и схемы совпадают с точностью атрибута sort_order и порядка колонок, тогда типы колонок выходной таблицы совпадает с типами в схемах входных таблиц. Ключевые колонки берутся из спецификации операции (sort_by ). Если все входные таблицы имеют слабую схему, схема будет выведена из ключевых колонок. |
from_output |
Сохраняется схема выходной таблицы, ключевые колонки меняются в соответствии с параметром спецификации sort_by . Все ключевые колонки должны присутствовать в схеме. |
auto |
При наличии сильной схемы у выходной таблицы проверяется, что она совместима по типам со схемой всех сильно схематизированных входных таблиц. Ключевые колонки меняются в соответствии со спецификацией. При наличии слабой схемы у выходной таблицы, схема выводится из схем входных таблиц (аналогично опции from_input ). |
Изменение схемы
Изменение схемы — легкая операция над метаинформацией, не требующая чтения данных. Для изменения схемы используйте команду alter_table
.
Схему пустой таблицы можно менять произвольным образом. Для непустых таблиц существует несколько разрешенных сценариев изменения схемы:
- добавление неключевой колонки в строгую схему —
strict = %true
; - добавление ключевой колонки в конец ключа в строгую схему —
strict = %true
; - удаление колонки из нестрогой схемы —
strict = %false
; - изменение схемы из строгой (
strict = %true
) на нестрогую (strict = %false
).
Прочие изменения схемы запрещены, так как они требует перевалидации данных, и такие изменения можно выполнить через операции Merge
или Map
.
На изменение схемы действует ряд ограничений:
- Изменение схемы не должно вызывать необходимость изменения содержимого таблицы. Например, изменение атрибута
strict
таблицы сfalse
наtrue
требует проверки, что каждая строка в таблице содержит только значения, относящиеся к столбцам, упомянутым в схеме, а подобная проверка эквивалентна полному прочтению таблицы. - Нельзя удалять столбцы при условии, что
strict = true
: нет возможности очистить соответствующее значение в каждой строке. Нельзя добавлять столбцы при условииstrict = false
: добавляя столбец некоторого типа, нельзя быть уверенным, что в таблице нет строк, уже содержащих значение, отвечающее этому столбцу, а оно уже может относиться к другому типу данных. - Нельзя удалять ключевые столбцы из середины, так как это может потенциально нарушить порядок сортировки.
- Нельзя вводить новые вычислимые колонки или менять выражение или функцию агрегации у имеющихся, так как это бы потребовало пересчёта во всех строках таблицы. Но, например, удалять последние ключевые колонки можно, так как это лишь ослабляет условие сортировки для будущих вставок, не меняя его для имеющегося набора строк.
Примеры работы со схемой
Чтение схемы
-
CLI
yt --proxy <cluster-name> get //home/tutorial/links_sorted_schematized/@schema
-
Python
yt.get("//home/tutorial/links_sorted_schematized/@schema")
Создание таблицы со схемой
-
CLI
yt --proxy <cluster-name> create table //tmp/table --attributes '{schema = [{name = a; type = int64}; {name = b; type = string}]}'
-
Python
yt.create_table("//tmp/table", attributes={"schema" : [{"name" : "a", "type" : "int64"}, {"name" : "b", "type" : "string"}]})
-
C++
auto schemaNode = TNode::CreateList() .Add(TNode()("name", "a")("type", "int64")) .Add(TNode()("name", "b")("type", "string")); client->Create( "//tmp/table", NYT::NT_TABLE, TCreateOptions().Attributes(TNode()("schema", schemaNode)));
Атрибут schema в RichYPath
При записи данных c помощью команды write_table
или на выходе MapReduce операций можно использовать атрибут @schema
пути.
- CLI
cat data | yt write '<schema=[{name = a; type = int64}; {name = b; type = string}]>//tmp/table'
Установка схемы и изменение формата для типизированных и разложенных данных
CLI
# Включить поколоночный формат хранения
yt --proxy <cluster-name> set //tmp/table/@optimize_for scan
# Установить новую схему и переложить данные в новый формат хранения
yt --proxy <cluster-name> merge --mode ordered --src //tmp/table --dst '<schema=[{name = a; type = int64; sort_order = ascending}; {name = b; type = string}]>//tmp/table' --spec '{schema_inference_mode = from_output; force_transform = %true}'
Существуют более автоматические решения:
- Через YQL задать запрос вида
INSERT INTO "path/to/somewhere" SELECT * FROM "source/table"
. YQL попробует вывести схему, прочитав первую или первые строки.