Любые способы использовать «пробел: удалить» частью частичного ключа в Tarantool? - PullRequest
1 голос
/ 03 июня 2019

В документации написано, что «удаление не может работать с частичными ключами». Какова ваша рекомендация, как ее решить. Например, создать новый индекс, использовать цикл удаления или любой другой способ?

Ответы [ 2 ]

1 голос
/ 07 июня 2019

Начиная с Tarantool 2.1, вы можете использовать для этого синтаксис SQL ('delete from ... where ...').

Однако имейте в виду, что Tarantool попытается выполнить это в транзакции, поэтому, если вы пытаетесь удалить слишком много кортежей, он на некоторое время заблокирует поток транзакции.

1 голос
/ 03 июня 2019

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

#!/usr/bin/env tarantool

local json = require('json')

local function key_from_tuple(tuple, key_parts)
    local key = {}
    for _, part in ipairs(key_parts) do
        table.insert(key, tuple[part.fieldno] or box.NULL)
    end
    return key
end

box.cfg{}

box.once('init', function()
    box.schema.space.create('s')
    box.space.s:create_index('pk')
    box.space.s:create_index('sk', {
        unique = false,
        parts = {
            {2, 'number'},
            {3, 'number'},
        }
    })
end)

box.space.s:truncate()
box.space.s:insert{1, 1, 1}
box.space.s:insert{2, 1, 1}

print('before delete')
print('---')
box.space.s:pairs():each(function(tuple)
    print(json.encode(tuple))
end)
print('...')

local key_parts = box.space.s.index.pk.parts
for _, tuple in box.space.s.index.sk:pairs({1}) do
    local key = key_from_tuple(tuple, key_parts)
    box.space.s.index.pk:delete(key)
end

print('after delete')
print('---')
box.space.s:pairs():each(function(tuple)
    print(json.encode(tuple))
end)
print('...')

os.exit()

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

for _, tuple in box.space.s.index.sk:pairs({1}) do
    box.space.s.index.pk:delete(tuple[1])
end

Новый модуль key_def, который был добавлен в tarantool-2.2.0-255-g22db9c264 (еще не выпущен, но доступен из нашего репозитория 2.2), упрощает извлечениеключ из кортежа, особенно в случае индексов пути json:

#!/usr/bin/env tarantool

local json = require('json')
local key_def_lib = require('key_def')

box.cfg{}

box.once('init', function()
    box.schema.space.create('s')
    box.space.s:create_index('pk')
    box.space.s:create_index('sk', {
        unique = false,
        parts = {
            {2, 'number', path = 'a'},
            {2, 'number', path = 'b'},
        }
    })
end)

box.space.s:truncate()
box.space.s:insert{1, {a = 1, b = 1}}
box.space.s:insert{2, {a = 1, b = 2}}

print('before delete')
print('---')
box.space.s:pairs():each(function(tuple)
    print(json.encode(tuple))
end)
print('...')

local key_def = key_def_lib.new(box.space.s.index.pk.parts)
for _, tuple in box.space.s.index.sk:pairs({1}) do
    local key = key_def:extract_key(tuple)
    box.space.s.index.pk:delete(key)
end

print('after delete')
print('---')
box.space.s:pairs():each(function(tuple)
    print(json.encode(tuple))
end)
print('...')

os.exit()

( источник кода )

...