【问题标题】:Any ways to use "space:delete" by part of partial key in Tarantool?有什么方法可以通过 Tarantool 中的部分键使用“空格:删除”?
【发布时间】:2019-10-19 06:33:22
【问题描述】:

文档说“删除不能使用部分键”。你有什么建议如何解决它。例如创建新索引,使用循环删除或任何方式?

【问题讨论】:

    标签: tarantool


    【解决方案1】:

    您可以使用主键在循环中删除值。

    #!/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
    

    在 tarantool-2.2.0-255-g22db9c264(尚未发布,但可从我们的 2.2 存储库中获得)中添加的新 key_def 模块简化了从元组中提取密钥的过程,尤其是在 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()
    

    (source of the code)

    【讨论】:

    • 谢谢! pair() 和 select() 有什么区别?
    • select() 一次将所有匹配的元组提取到 Lua 内存中,如果达到 Lua 内存限制(2 GiB AFAIR),这可能会导致 Lua 错误。 pair() 创建一个迭代器,可以用for tuple-by-tuple 遍历。这里的一般建议是仅在您确定结果集很小时才使用 select()。
    【解决方案2】:

    从 Tarantool 2.1 开始,您可以为此使用 SQL 语法('delete from ... where ...')。

    但是,请注意,Tarantool 会尝试在事务中执行此操作,因此如果您尝试删除太多元组,它会锁定事务线程一段时间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-01
      • 2012-06-14
      • 2017-04-21
      • 1970-01-01
      相关资源
      最近更新 更多