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

Примеры CRUD-операций

Использование операций с данными

В этом разделе приведены базовые сценарии использования и типичные ошибки для каждой операции с данными в Tarantool: INSERT, DELETE, UPDATE, UPSERT, REPLACE и SELECT. Перед выполнением примеров необходимо выполнить начальную загрузку экземпляра Tarantool, как показано ниже.

-- Create a space --bands = box.schema.space.create('bands')-- Specify field names and types --box.space.bands:format({    { name = 'id', type = 'unsigned' },    { name = 'band_name', type = 'string' },    { name = 'year', type = 'unsigned' }})-- Create a primary index --box.space.bands:create_index('primary', { parts = { 'id' } })-- Create a unique secondary index --box.space.bands:create_index('band', { parts = { 'band_name' } })-- Create a non-unique secondary index --box.space.bands:create_index('year', { parts = { { 'year' } }, unique = false })-- Create a multi-part index --box.space.bands:create_index('year_band', { parts = { { 'year' }, { 'band_name' } } })

INSERT

Метод space_object.insert принимает корректно сформированный кортеж.

-- Insert a tuple with a unique primary key --tarantool> bands:insert{1, 'Scorpions', 1965}---- [1, 'Scorpions', 1965]...

insert также проверяет все ключи на дубликаты.

-- Try to insert a tuple with a duplicate primary key --tarantool> bands:insert{1, 'Scorpions', 1965}---- error: Duplicate key exists in unique index "primary" in space "bands" with old    tuple - [1, "Scorpions", 1965] and new tuple - [1, "Scorpions", 1965]...-- Try to insert a tuple with a duplicate secondary key --tarantool> bands:insert{2, 'Scorpions', 1965}---- error: Duplicate key exists in unique index "band" in space "bands" with old tuple    - [1, "Scorpions", 1965] and new tuple - [2, "Scorpions", 1965]...-- Insert a second tuple with unique primary and secondary keys --tarantool> bands:insert{2, 'Pink Floyd', 1965}---- [2, 'Pink Floyd', 1965]...-- Delete all tuples --tarantool> bands:truncate()---...

DELETE

Метод space_object.delete позволяет удалить кортеж по первичному ключу.

-- Insert test data --tarantool> bands:insert{1, 'Roxette', 1986}           bands:insert{2, 'Scorpions', 1965}           bands:insert{3, 'Ace of Base', 1987}           bands:insert{4, 'The Beatles', 1960}-- Delete a tuple with an existing key --tarantool> bands:delete{4}---- [4, 'The Beatles', 1960]...tarantool> bands:select()---- - [1, 'Roxette', 1986]  - [2, 'Scorpions', 1965]  - [3, 'Ace of Base', 1987]...

Для удаления кортежа по указанному уникальному индексу также можно использовать index_object.delete.

-- Delete a tuple by the primary index --tarantool> bands.index.primary:delete{3}---- [3, 'Ace of Base', 1987]...tarantool> bands:select()---- - [1, 'Roxette', 1986]  - [2, 'Scorpions', 1965]...-- Delete a tuple by a unique secondary index --tarantool> bands.index.band:delete{'Scorpions'}---- [2, 'Scorpions', 1965]...tarantool> bands:select()---- - [1, 'Roxette', 1986]...-- Try to delete a tuple by a non-unique secondary index --tarantool> bands.index.year:delete(1986)---- error: Get() doesn't support partial keys and non-unique indexes...tarantool> bands:select()---- - [1, 'Roxette', 1986]...-- Try to delete a tuple by a partial key --tarantool> bands.index.year_band:delete('Roxette')---- error: Invalid key part count in an exact match (expected 2, got 1)...-- Delete a tuple by a full key --tarantool> bands.index.year_band:delete{1986, 'Roxette'}---- [1, 'Roxette', 1986]...tarantool> bands:select()---- ...-- Delete all tuples --tarantool> bands:truncate()---...

UPDATE

Метод space_object.update позволяет обновить кортеж по первичному ключу. Как и delete, метод update принимает полный ключ, а также операцию для выполнения.

-- Insert test data --tarantool> bands:insert{1, 'Roxette', 1986}           bands:insert{2, 'Scorpions', 1965}           bands:insert{3, 'Ace of Base', 1987}           bands:insert{4, 'The Beatles', 1960}-- Update a tuple with an existing key --tarantool> bands:update({2}, {{'=', 2, 'Pink Floyd'}})---- [2, 'Pink Floyd', 1965]...tarantool> bands:select()---- - [1, 'Roxette', 1986]  - [2, 'Pink Floyd', 1965]  - [3, 'Ace of Base', 1987]  - [4, 'The Beatles', 1960]...

Метод index_object.update обновляет кортеж по указанному уникальному индексу.

-- Update a tuple by the primary index --tarantool> bands.index.primary:update({2}, {{'=', 2, 'The Rolling Stones'}})---- [2, 'The Rolling Stones', 1965]...tarantool> bands:select()---- - [1, 'Roxette', 1986]  - [2, 'The Rolling Stones', 1965]  - [3, 'Ace of Base', 1987]  - [4, 'The Beatles', 1960]...-- Update a tuple by a unique secondary index --tarantool> bands.index.band:update({'The Rolling Stones'}, {{'=', 2, 'The Doors'}})---- [2, 'The Doors', 1965]...tarantool> bands:select()---- - [1, 'Roxette', 1986]  - [2, 'The Doors', 1965]  - [3, 'Ace of Base', 1987]  - [4, 'The Beatles', 1960]...-- Try to update a tuple by a non-unique secondary index --tarantool> bands.index.year:update({1965}, {{'=', 2, 'Scorpions'}})---- error: Get() doesn't support partial keys and non-unique indexes...tarantool> bands:select()---- - [1, 'Roxette', 1986]  - [2, 'The Doors', 1965]  - [3, 'Ace of Base', 1987]  - [4, 'The Beatles', 1960]...-- Delete all tuples --tarantool> bands:truncate()---...

UPSERT

Метод space_object.upsert обновляет существующий кортеж или вставляет новый:

  • Если существующий кортеж найден по первичному ключу, Tarantool применяет к нему операцию обновления и игнорирует новый кортеж.

  • Если существующий кортеж не найден, Tarantool вставляет новый кортеж и игнорирует операцию обновления.

tarantool> bands:insert{1, 'Scorpions', 1965}---- [1, 'Scorpions', 1965]...-- As the first argument, upsert accepts a tuple, not a key --tarantool> bands:upsert({2}, {{'=', 2, 'Pink Floyd'}})---- error: Tuple field 2 (band_name) required by space format is missing...tarantool> bands:select()---- - [1, 'Scorpions', 1965]...tarantool> bands:delete(1)---- [1, 'Scorpions', 1965]...

Метод upsert действует как insert, если существующий кортеж не найден по первичному ключу.

tarantool> bands:upsert({1, 'Scorpions', 1965}, {{'=', 2, 'The Doors'}})---...-- As you can see, {1, 'Scorpions', 1965} is inserted, ---- and the update operation is not applied. --tarantool> bands:select()---- - [1, 'Scorpions', 1965]...-- upsert with the same primary key but different values in other fields ---- applies the update operation and ignores the new tuple. --tarantool> bands:upsert({1, 'Scorpions', 1965}, {{'=', 2, 'The Doors'}})---...tarantool> bands:select()---- - [1, 'The Doors', 1965]...

Метод upsert выполняет поиск существующего кортежа по первичному индексу, а не по вторичному. Это может привести к ошибке дублирования, если кортеж нарушает уникальность вторичного индекса.

tarantool> bands:upsert({2, 'The Doors', 1965}, {{'=', 2, 'Pink Floyd'}})---- error: Duplicate key exists in unique index "band" in space "bands" with old tuple    - [1, "The Doors", 1965] and new tuple - [2, "The Doors", 1965]...tarantool> bands:select()---- - [1, 'The Doors', 1965]...-- This works if uniqueness is preserved. --tarantool> bands:upsert({2, 'The Beatles', 1960}, {{'=', 2, 'Pink Floyd'}})---...tarantool> bands:select()---- - [1, 'The Doors', 1965]  - [2, 'The Beatles', 1960]...-- Delete all tuples --tarantool> bands:truncate()---...

REPLACE

space_object.replace принимает корректно сформированный кортеж и выполняет поиск существующего кортежа по первичному ключу нового кортежа:

  • Если существующий кортеж найден, Tarantool удаляет его и вставляет новый кортеж.

  • Если существующий кортеж не найден, Tarantool вставляет новый кортеж.

tarantool> bands:replace{1, 'Scorpions', 1965}---- [1, 'Scorpions', 1965]...tarantool> bands:select()---- - [1, 'Scorpions', 1965]...tarantool> bands:replace{1, 'The Beatles', 1960}---- [1, 'The Beatles', 1960]...tarantool> bands:select()---- - [1, 'The Beatles', 1960]...tarantool> bands:truncate()---...

Метод replace может нарушить ограничения уникальности, как и upsert.

tarantool> bands:insert{1, 'Scorpions', 1965}- [1, 'Scorpions', 1965]...tarantool> bands:insert{2, 'The Beatles', 1960}---- [2, 'The Beatles', 1960]...tarantool> bands:replace{2, 'Scorpions', 1965}---- error: Duplicate key exists in unique index "band" in space "bands" with old tuple    - [1, "Scorpions", 1965] and new tuple - [2, "Scorpions", 1965]...tarantool> bands:truncate()---...

SELECT

Запрос space_object.select выполняет поиск кортежа или набора кортежей в указанном спейсе по первичному ключу. Для поиска по указанному индексу используйте index_object.select. Эти методы работают с любыми ключами, включая уникальные и неуникальные, полные и частичные. Если ключ частичный, select выполняет поиск по всем ключам, префикс которых совпадает с указанной частью ключа.

tarantool> bands:insert{1, 'Roxette', 1986}           bands:insert{2, 'Scorpions', 1965}           bands:insert{3, 'The Doors', 1965}           bands:insert{4, 'The Beatles', 1960}tarantool> bands:select(1)---- - [1, 'Roxette', 1986]...tarantool> bands:select()---- - [1, 'Roxette', 1986]  - [2, 'Scorpions', 1965]  - [3, 'The Doors', 1965]  - [4, 'The Beatles', 1960]...tarantool> bands.index.primary:select(2)---- - [2, 'Scorpions', 1965]...tarantool> bands.index.band:select('The Doors')---- - [3, 'The Doors', 1965]...tarantool> bands.index.year:select(1965)---- - [2, 'Scorpions', 1965]  - [3, 'The Doors', 1965]...

Использование функций box.space для чтения кортежей space

В этом примере показано, как просмотреть все спейсы и для каждого вывести: приблизительное количество кортежей и первое поле первого кортежа. Функция использует функции box.space из Tarantool — len() и pairs(). Перебор спейсов реализован как сканирование системного спейса _space, который содержит метаданные. Третье поле в _space содержит имя спейса, поэтому ключевая инструкция space_name = v[3] означает, что space_name — это поле space_name в кортеже _space, только что полученном с помощью pairs(). Функция возвращает таблицу:

function example()  local tuple_count, space_name, line  local ta = {}  for k, v in box.space._space:pairs() do    space_name = v[3]    if box.space[space_name].index[0] ~= nil then      tuple_count = '1 or more'    else      tuple_count = '0'    end    line = space_name .. ' tuple_count =' .. tuple_count    if tuple_count == '1 or more' then      for k1, v1 in box.space[space_name]:pairs() do        line = line .. '. first field in first tuple = ' .. v1[1]        break      end    end    table.insert(ta, line)  end  return taend

Ниже показан результат вызова этой функции:

tarantool> example()---- - _schema tuple_count =1 or more. first field in first tuple = cluster  - _space tuple_count =1 or more. first field in first tuple = 272  - _vspace tuple_count =1 or more. first field in first tuple = 272  - _index tuple_count =1 or more. first field in first tuple = 272  - _vindex tuple_count =1 or more. first field in first tuple = 272  - _func tuple_count =1 or more. first field in first tuple = 1  - _vfunc tuple_count =1 or more. first field in first tuple = 1  - _user tuple_count =1 or more. first field in first tuple = 0  - _vuser tuple_count =1 or more. first field in first tuple = 0  - _priv tuple_count =1 or more. first field in first tuple = 1  - _vpriv tuple_count =1 or more. first field in first tuple = 1  - _cluster tuple_count =1 or more. first field in first tuple = 1...

Использование функций box.space для организации кортежа space

В этом примере показано, как вывести имена и типы полей системного спейса — использование метаданных для поиска метаданных.

Для начала: как можно сделать выборку кортежа из _space, который описывает _space?

Простой способ — посмотреть константы в box.schema, где видно, что есть элемент с именем SPACE_ID == 288, поэтому следующие инструкции возвращают нужный кортеж:

box.space._space:select{ 288 }-- или --box.space._space:select{ box.schema.SPACE_ID }

Другой способ — посмотреть кортежи в box.space._index, где видно, что для спейса с номером 288 существует вторичный индекс с именем 'name', поэтому следующая инструкция также возвращает нужный кортеж:

box.space._space.index.name:select{ '_space' }

Однако непросто прочитать информацию из полученного кортежа:

tarantool> box.space._space.index.name:select{'_space'}---- - [280, 1, '_space', 'memtx', 0, {}, [{'name': 'id', 'type': 'num'}, {'name': 'owner',        'type': 'num'}, {'name': 'name', 'type': 'str'}, {'name': 'engine', 'type': 'str'},      {'name': 'field_count', 'type': 'num'}, {'name': 'flags', 'type': 'str'}, {        'name': 'format', 'type': '*'}]]...

Информация подается бессистемно, поскольку по формату поле №7 содержит рекомендованные имена и типы данных. Как же получить эти данные? Поскольку очевидно, что поле №7 представляет собой ассоциативный массив, цикл for проведет организацию данных:

tarantool> do         >   local tuple_of_space = box.space._space.index.name:get{'_space'}         >   for _, field in ipairs(tuple_of_space[7]) do         >     print(field.name .. ', ' .. field.type)         >   end         > endid, numowner, numname, strengine, strfield_count, numflags, strformat, *---...