Using indexes
Перед тем, как вставлять кортежи в спейс или выбирать из него кортежи, нужно обязательно создать индекс для этого спейса.
Простая операция по созданию индекса выглядит следующим образом:
box.space.space-name:create_index('index-name')
При этом создается уникальный TREE-индекс по первому полю всех кортежей (обычно его называют «Field#1»). Предполагается, что индексируемое поле является числовым.
Рекомендуется проектировать модель данных так, чтобы первичные ключи были первыми полями в кортеже. Это позволяет быстрее сравнивать кортежи, учитывая специфику хранения данных и способ организации сравнений в Tarantool.
Вот простой запрос SELECT:
box.space.space-name:select(value)
Такой запрос ищет отдельный кортеж, используя первичный индекс. Поскольку первичный индекс всегда уникален, то данный запрос вернет не более одного кортежа. Можно также вызвать select()
без аргументов, чтобы вернуть все кортежи. Осторожно! Если вызвать select()
без аргументов в огромном спейсе, ваш экземпляр зависнет.
Определение индекса может также содержать идентификаторы полей кортежа и их предполагаемые типы. См. допустимые типы полей в разделе Описание типов индексируемых полей:
box.space.space-name:create_index(index-name, {type = 'tree', parts = {{field = 1, type = 'unsigned'}}}
Определения спейса и определения индексов хранятся в системных спейсах Tarantool _space и _index соответственно.
Примечание
Полную информацию о создании индексов, например о создании индексов по массиву (multikey), индексов с использованием пути path
или функциональных индексов см. в справочнике space_object:create_index().
Операции с индексами производятся автоматически. Если запрос на изменение данных меняет данные в кортеже, то изменятся и ключи индекса для данного кортежа.
Для примера создадим спейс с именем
tester
и поместим его в переменнуюmy_space
:tarantool> my_space = box.schema.space.create('tester')
Отформатируем созданный спейс, указав имена и типы полей:
tarantool> my_space:format({ > {name = 'id', type = 'unsigned'}, > {name = 'band_name', type = 'string'}, > {name = 'year', type = 'unsigned'}, > {name = 'rate', type = 'unsigned', is_nullable = true}})
Создадим первичный индекс с именем
primary
:tarantool> my_space:create_index('primary', { > type = 'tree', > parts = {'id'} > })
Это первичный индекс по полю
id
в каждом кортеже.Вставим несколько кортежей в спейс:
tarantool> my_space:insert{1, 'Roxette', 1986, 1} tarantool> my_space:insert{2, 'Scorpions', 2015, 4} tarantool> my_space:insert{3, 'Ace of Base', 1993} tarantool> my_space:insert{4, 'Roxette', 2016, 3}
Создадим вторичный индекс:
tarantool> box.space.tester:create_index('secondary', {parts = {{field=3, type='unsigned'}}}) --- - unique: true parts: - type: unsigned is_nullable: false fieldno: 3 id: 2 space_id: 512 type: TREE name: secondary ...
Создадим составной индекс (multi-part) из трех частей:
tarantool> box.space.tester:create_index('thrine', {parts = { > {field = 2, type = 'string'}, > {field = 3, type = 'unsigned'}, > {field = 4, type = 'unsigned'} > }}) --- - unique: true parts: - type: string is_nullable: false fieldno: 2 - type: unsigned is_nullable: false fieldno: 3 - type: unsigned is_nullable: true fieldno: 4 id: 6 space_id: 513 type: TREE name: thrine ...
Можно использовать такие варианты SELECT:
Помимо условия равенства, при поиске могут использоваться и другие условия сравнения:
tarantool> box.space.tester:select(1, {iterator = 'GT'}) --- - - [2, 'Scorpions', 2015, 4] - [3, 'Ace of Base', 1993] - [4, 'Roxette', 2016, 3] ...
Есть такие операторы сравнения:
LT
— «меньше»LE
— «меньше или равно»GT
— «больше»GE
— «больше или равно»EQ
— «равно»,REQ
— «равно, результаты отсортированы в порядке убывания по ключу»
Только для TREE-индексов есть смысл в сравнении значений. Итераторы для других типов индексов немного отличаются и работают по-другому. Более подробную информацию см. в разделе Типы итераторов.
Обратите внимание, что мы не используем имя индекса — значит, здесь мы используем первичный индекс.
Этот вариант поиска может вернуть более одного кортежа. Если используется оператор сравнения LT, LE или REQ, то кортежи будут отсортированы по ключу в порядке убывания. Во всех остальных случаях — в порядке возрастания.
Для поиска можно использовать вторичный индекс.
При поиске по первичному ключу имя индекса можно не указывать, как показано выше. При поиске же по вторичному ключу имя индекса нужно указать обязательно.
tarantool> box.space.tester.index.secondary:select({1993}) --- - - [3, 'Ace of Base', 1993] ...
Поиск по частям ключа: Можно производить поиск по частям ключа, начиная с префикса ключа. Обратите внимание, что поиск по части ключа доступен только в TREE-индексах.
tarantool> box.space.tester.index.thrine:select({'Scorpions', 2015}) --- - - [2, 'Scorpions', 2015, 4] ...
Поиск можно производить по всем полям через запись в виде таблицы:
tarantool> box.space.tester.index.thrine:select({'Roxette', 2016, 3}) --- - - [4, 'Roxette', 2016, 3] ...
либо же по одному полю, в этом случае используется таблица или скалярное значение:
tarantool> box.space.tester.index.thrine:select({'Roxette'}) --- - - [1, 'Roxette', 1986, 5] - [4, 'Roxette', 2016, 3] ...
Примечание
С некоторыми ограничениями можно добавлять, удалять или изменять определения во время исполнения кода. Более подробную информацию об операциях с индексами см. в справочнике по вложенному модулю box.index.