Using indexes | Tarantool
Документация на русском языке
поддерживается сообществом

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().

Операции с индексами производятся автоматически. Если запрос на изменение данных меняет данные в кортеже, то изменятся и ключи индекса для данного кортежа.

  1. Для примера создадим спейс с именем tester и поместим его в переменную my_space:

    tarantool> my_space = box.schema.space.create('tester')
    
  2. Отформатируем созданный спейс, указав имена и типы полей:

    tarantool> my_space:format({
             > {name = 'id', type = 'unsigned'},
             > {name = 'band_name', type = 'string'},
             > {name = 'year', type = 'unsigned'},
             > {name = 'rate', type = 'unsigned', is_nullable = true}})
    
  3. Создадим первичный индекс с именем primary:

    tarantool> my_space:create_index('primary', {
             > type = 'tree',
             > parts = {'id'}
             > })
    

    Это первичный индекс по полю id в каждом кортеже.

  4. Вставим несколько кортежей в спейс:

    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}
    
  5. Создадим вторичный индекс:

    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
    ...
    
  6. Создадим составной индекс (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]
    ...
    
  • Поиск можно производить по всем полям через запись в виде таблицы:

    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.

Нашли ответ на свой вопрос?
Обратная связь