Схема данных

Общее описание

Схема таблицы описывает известные колонки и их типы.

Схему можно прочитать из системного атрибута @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 попробует вывести схему, прочитав первую или первые строки.
Предыдущая
Следующая