【问题标题】:How do I select a limited number of records from tarantool, like with SELECT LIMIT in SQL?如何从 tarantool 中选择有限数量的记录,例如 SQL 中的 SELECT LIMIT?
【发布时间】:2019-10-28 06:11:03
【问题描述】:

我想在 Tarantool 空间上执行选择,使用过滤和限制结果,就像我可以使用简单的 SQL 查询一样 “SELECT * FROM users WHERE age > 33 LIMIT 1”。 我怎样才能做到这一点?

【问题讨论】:

    标签: sql tarantool


    【解决方案1】:

    可以使用 Lua 和 SQL 来完成。

    1) 这是 Lua 中的示例。假设我们有一个名为“users”的空间,其中包含“name”、“surname”、“age”字段。首先,让我们创建并填充空间:

    $ tarantool
    Tarantool 2.1.1-465-gbd1a43fbc
    type 'help' for interactive help
    tarantool> box.cfg({})
    ...
    2019-06-10 14:51:33.827 [47393] main/102/interactive I> ready to accept requests
    ...
    2019-06-10 14:51:33.827 [47393] main/104/checkpoint_daemon I> scheduled next checkpoint for Mon Jun 10 16:14:44 2019
    ---
    ...
    
    tarantool> s = box.schema.space.create('users', {temporary=true})
    ---
    ...
    
    tarantool> box.space.users:format({{'id','unsigned'},{'name','string'},{'surname','string'},{'age','unsigned'}})
    ---
    ...
    
    tarantool> s:create_index('primary', {unique = true, parts = {1, 'unsigned'}})
    ---
    - unique: true
      parts:
      - type: unsigned
        is_nullable: false
        fieldno: 1
      id: 0
      space_id: 512
      name: primary
      type: TREE
    ...
    
    tarantool> s:insert({1,'Pasha','Yudin',33})
    ---
    - [1, 'Pasha', 'Yudin', 33]
    ...
    
    tarantool> s:insert({3,'Kostya','Nazarov',34})
    ---
    - [2, 'Kostya', 'Nazarov', 34]
    ...
    
    tarantool> s:insert({2,'Oleg','Babin',23})
    ---
    - [3, 'Oleg', 'Babin', 23]
    ...
    
    tarantool> s:insert({4,'Roma','Babaev',34})
    ---
    - [4, 'Roma', 'Babaev', 34]
    ...
    

    让我们从空间中选择所有记录:

    tarantool> s:select()
    ---
    - - [1, 'Pasha', 'Yudin', 33]
      - [2, 'Kostya', 'Nazarov', 23]
      - [3, 'Oleg', 'Babin', 34]
      - [4, 'Roma', 'Babaev', 34]
    ...
    

    接下来,让我们选择所有 33 岁以上的用户。可以使用LuaFun 库:

    tarantool> fun = require('fun')
    ---
    ...
    
    tarantool> fun.iter(s:select()):filter(function (tuple) return tuple.age > 33 end):totable()
    ---
    - - [3, 'Oleg', 'Babin', 34]
      - [4, 'Roma', 'Babaev', 34]
    ...
    

    但正如下面提到的@AlexanderTurenko,最好使用pairs 迭代器来避免将额外的元组加载到内存中:

    tarantool> s:pairs():filter(function (tuple) return tuple.age > 33 end):totable()
    ---
    - - [3, 'Oleg', 'Babin', 34]
      - [4, 'Roma', 'Babaev', 34]
    ...
    

    此外,这个变体更短,更易读。

    最后,我们只选择一个符合我们条件的用户,相当于SQL查询“SELECT * FROM users WHERE age > 33 LIMIT 1”:

    tarantool> s:pairs():filter(function (tuple) return tuple.age > 33 end):take_n(1):totable()
    ---
    - - [3, 'Oleg', 'Babin', 34]
    ...
    

    2) 从 Tarantool 2.0 开始,可以做到using SQL(前提是你有空格格式):

    box.execute('select * from users where age > 33 limit 1;')
    

    【讨论】:

    • 通常最好使用s:pairs():filter(<...>):take(<...>):totable()而不是fun.iter(s:select()):filter(<...>):take(<...>):totable(),这样就不会将更多的元组获取到Lua内存中。
    • 感谢您提供详细示例!
    猜你喜欢
    • 2019-10-29
    • 1970-01-01
    • 2020-09-28
    • 2013-07-05
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    • 2019-01-26
    • 1970-01-01
    相关资源
    最近更新 更多