Tarantool CE/EE Documentation portal logo
Помощь
Обновлена 15 сентября 2026 г. в 08:55

Модуль key_def

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

key_def.new(parts)

Создание нового экземпляра key_def.

Параметры:

  • parts (table) — номера и типы полей. Должен быть указан хотя бы один компонент. Каждый компонент должен содержать атрибуты type и fieldno/field. Остальные атрибуты необязательны.

Возвращает

объект key_def

Таблица parts содержит компоненты, аналогичные тем, что указываются в параметре parts при создании объекта space_object:create_index():

  • fieldno (целое число), например fieldno = 1. Вместо fieldno можно использовать field.
  • type (строка), например type = 'string'.

Остальные компоненты необязательны.

Пример №1: key_def.new({{type = 'unsigned', fieldno = 1}})

Пример №2: key_def.new({{type = 'string', collation = 'unicode', field = 2}})

Начиная с версии 3.2.0, для проверки длины объекта key_def (количества компонентов) можно использовать стандартный оператор Lua # (метаметод __len).

Пример:

function is_full_pkey(space, key)    return #space.index[0].parts == #keyend

key_def_object

Объект key_def — это объект, возвращаемый функцией key_def.new(). У него есть следующие методы: extract_key(), compare(), compare_with_key(), merge(), totable().

key_def_object:extract_key(tuple)

Получение кортежа, содержащего только поля объекта key_def.

Параметры:

  • tuple (table) — кортеж или Lua-таблица со значениями полей

Возвращает

поля, определенные для объекта key_def

Пример №1:

-- Suppose an item has five fields-- 1, 99.5, 'X', nil, 99.5-- and the fields that we care about are-- #3 (a string) and #1 (an integer).-- We can define those fields with k = key_def.new-- and extract the values with k:extract_key.tarantool> key_def = require('key_def')---...tarantool> k = key_def.new({{type = 'string', fieldno = 3},                          {type = 'unsigned', fieldno = 1}})---...tarantool> k:extract_key({1, 99.5, 'X', nil, 99.5})---- ['X', 1]...

Пример №2:

-- Теперь предположим, что элемент является кортежем в спейсе.-- У спейса есть составной индекс, построенный по полям 3 и 1.-- Мы можем передать определение индекса в качестве аргумента функции key_def.new,-- а не заполнять определение, как в примере №1.-- Результат будет тот же.key_def = require('key_def')box.schema.space.create('T')i = box.space.T:create_index('I', {parts={3, 'string', 1, 'unsigned'}})box.space.T:insert{1, 99.5, 'X', nil, 99.5}k = key_def.new(i.parts)k:extract_key(box.space.T:get({'X', 1}))

Пример №3:

-- Проходим по всем кортежам во вторичном неуникальном индексе-- и извлекаем из них значения по первичному ключу.-- Затем удаляем значения, используя уникальный индекс.-- Этот код должен входить в Lua-функцию.local key_def_lib = require('key_def')local s = box.schema.space.create('test')local pk = s:create_index('pk')local sk = s:create_index('test', {unique = false, parts = {    {2, 'number', path = 'a'}, {2, 'number', path = 'b'}})s:insert{1, {a = 1, b = 1}}s:insert{2, {a = 1, b = 2}}local key_def = key_def_lib.new(pk.parts)for _, tuple in sk:pairs({1}) do    local key = key_def:extract_key(tuple)    pk:delete(key)end

key_def_object:compare(tuple_1, tuple_2)

Сравнение полей кортежей tuple_1 и tuple_2 по определённому ключу. Пользователю не нужно писать код для сравнения отдельных полей. Учитываются типы полей и параметры сортировки. Фактически сравниваются значения extract_key(tuple_1) и extract_key(tuple_2).

Параметры:

  • tuple_1 (table) — кортеж или Lua-таблица со значениями полей
  • tuple_2 (table) — кортеж или Lua-таблица со значениями полей

Возвращает

  • <0, если ключевые поля tuple_1 меньше ключевых полей tuple_2
  • 0, если ключевые поля tuple_1 равны ключевым полям tuple_2
  • >0, если ключевые поля tuple_1 больше ключевых полей tuple_2

Пример:

-- Результат этого кода будет 0key_def = require('key_def')k = key_def.new({{type = 'string', fieldno = 3, collation = 'unicode_ci'},                 {type = 'unsigned', fieldno = 1}})k:compare({1, 99.5, 'X', nil, 99.5}, {1, 99.5, 'x', nil, 99.5})

key_def_object:compare_with_key(tuple_1, tuple_2)

Сравнение полей кортежей tuple_1 с полями кортежа tuple_2 по заданному ключу. Аналогично key_def_object:compare(), за исключением того, что tuple_2 содержит только поля ключа. Фактически это сравнение extract_key(tuple_1) с tuple_2.

Параметры:

  • tuple_1 (table) — кортеж или Lua-таблица со значениями полей
  • tuple_2 (table) — кортеж или Lua-таблица со значениями полей

Возвращает

  • <0, если ключевые поля tuple_1 меньше полей tuple_2
  • 0, если ключевые поля tuple_1 равны полям tuple_2
  • >0, если ключевые поля tuple_1 больше полей tuple_2

Пример:

-- Результат этого кода будет 0key_def = require('key_def')k = key_def.new({{type = 'string', fieldno = 3, collation = 'unicode_ci'},                 {type = 'unsigned', fieldno = 1}})k:compare_with_key({1, 99.5, 'X', nil, 99.5}, {'x', 1})

key_def_object:merge(other_key_def_object)

Объединение основного объекта key_def_object с другим объектом other_key_def_object. Возвращает новый объект key_def_object, содержащий сначала все поля основного объекта key_def_object, а потом те поля объекта other_key_def_object, которых не было в основном объекте key_def_object.

Параметры:

  • other_key_def_object (key_def_object) — определение добавляемых полей

Возвращает

key_def_object

Пример:

-- Результатом этого кода будет определение ключа-- по полям с fieldno = 3 и fieldno = 1key_def = require('key_def')k = key_def.new({{type = 'string', fieldno = 3}})k2 = key_def.new({{type = 'unsigned', fieldno = 1},                 {type = 'string', fieldno = 3}})k:merge(k2)

key_def_object:totable()

Возвращает таблицу с содержимым key_def_object. Функция противоположна функции key_def.new():

  • key_def.new() принимает таблицу и возвращает объект key_def,
  • key_def_object:totable() принимает объект key_def и возвращает таблицу.

Это удобно при подготовке входных данных для методов сериализации (_serialize).

Возвращает

таблица

Пример:

-- Результатом этого кода будет таблица с type = 'string', fieldno = 3key_def = require('key_def')k = key_def.new({{type = 'string', fieldno = 3}})k:totable()

key_def_object:validate_key(key)

Начиная с: 3.1.0

Проверка, что все части указанного ключа соответствуют определению ключа. Частичные ключи считаются допустимыми. При успешном выполнении ничего не возвращает.

Если ключ не проходит проверку, вызывается исключение типа box.error.

Пример:

-- Create a rule: key = {1 ('unsigned'), 2 (string)}-- Validate key {1001} (only id data type). Returns nothing-- Validate key {'x'}. ER_KEY_PART_TYPE is raised-- Validate key ({1000, 2000}). ER_KEY_PART_TYPE is raised-- Validate key ({1000, 'abc', 'xyz'}). ER_KEY_PART_COUNT is raisedtarantool> key_def = require('key_def').new({{fieldno = 1, type = 'unsigned'},                          {fieldno = 2, type = 'string'}})---...tarantool> key_def:validate_key({1001})---...tarantool> key_def:validate_key({'x'})---- error: 'Supplied key type of part 0 does not match index part type: expected unsigned'...tarantool> key_def:validate_key({1000, 2000})---- error: 'Supplied key type of part 1 does not match index part type: expected string'...tarantool> key_def:validate_key({1000, 'abc', 'xyz'})---- error: 'Invalid key part count: (expected [0..2], got 3)'...

key_def_object:validate_full_key(key)

Начиная с: 3.1.0

Проверка, что переданный key содержит все поля и соответствует правилам объекта определения ключа. При успешном выполнении ничего не возвращает.

Если ключ не проходит проверку, вызывается исключение типа box.error.

Пример:

-- Create a rule: key = {1 ('unsigned'), 2 (string)}-- Validate key {100, "Testuser"}. Returns nothing-- Validate key ({100}). ER_EXACT_MATCH is raisedtarantool> key_def = require('key_def').new({{fieldno = 1, type = 'unsigned'},                          {fieldno = 2, type = 'string'}})---...tarantool> key_def:validate_full_key({100, "Testuser"})---...tarantool> key_def:validate_full_key({100})---- error: 'Invalid key part count in an exact match: (expected 2, got 1)'...

key_def_object:validate_tuple(tuple)

Начиная с: 3.1.0

Проверка, что tuple соответствует правилам объекта определения ключа. При успешном выполнении ничего не возвращает.

Если ключ не проходит проверку, вызывается исключение типа box.error.

Пример:

-- Create a rule: tuple = {id (number), name (string), age (number)}-- Validate tuple {1001, "Testuser", 28}. Returns nothingtarantool> key_def = require('key_def').new({                          {fieldno = 1, type = 'number'},                          {fieldno = 2, type = 'string'},                          {fieldno = 3, type = 'number'})---...tarantool> key_def:validate_tuple({1001, "Testuser", 28})---...

key_def_object:compare_keys(key_a, key_b)

Начиная с: 3.1.0

Сравнение двух ключей друг с другом согласно объекту определения ключа. При успешном выполнении возвращает:

  • <0, если части key_a меньше частей key_b
  • 0, если части key_a равны частям key_b
  • >0, если части key_a больше частей key_b

Если какой-либо ключ не соответствует правилам определения ключа, вызывается исключение типа box.error.

Пример:

-- Create a rule: key = {1 ('unsigned'), 2 (string)}-- Validate keys ({1000, 'x'}, {1000, 'y'}). Returns -1-- Validate keys ({1000, 'x'}, {1000, 'x'}). Returns 0-- Validate keys ({1000, 'x'}, {1000}). Returns 0-- Validate keys ({2000, 'x'}, {1000, 'x'}). Returns 1tarantool> key_def = require('key_def').new({{fieldno = 1, type = 'unsigned'},                          {fieldno = 2, type = 'string'}})---...tarantool> key_def:compare_keys({1000, 'x'}, {1000, 'y'})---- -1...tarantool> key_def:compare_keys({1000, 'x'}, {1000, 'x'})---- 0...tarantool> key_def:compare_keys({1000, 'x'}, {1000})---- 0...tarantool> key_def:compare_keys({2000, 'x'}, {1000, 'x'})---- 1...