2013-01-24 35 views
0

我们的一个需求是创建一个临时内存数据库,然后执行各种插入/选择/更新。轻量级内存数据库

一目了然SQLite满足了我们所有的需求。连接到一个内存中的SQLite数据库,可以建立简单:

class SQLiteBase < ActiveRecord::Base 
    self.abstract_class = true 

    establish_connection(adapter: 'sqlite3', database: ':memory:') 
end 

前一段时间,我们已经开始寻找到一些服务表现的问题时,事实证明,我们需要进行批量加载(具体而言,散装INSERT))数据到我们的SQLite表(参见these基准)。

不幸的是,它看起来像SQLite不支持批量插入。

因此是否有任何其他基于SQL的轻量级内存数据库,支持批量插入

如果没有这样的 - 有没有一种方法可以像内存数据库一样利用重量级数据库,如PostreSQL(MySQL或任何其他主要播放器)?

如果postresql/mysql不是一种可行的方式 - 是否还有其他C语言重度优化的数据结构,并在其上面有查询语言? (有/无红宝石绑定)。

+0

您在这些测试中是否正确使用内存数据库中的事务? –

回答

2

首先,SQLite的确实使用下面的方法支持批量插入:

  • 穷人的替代品多值INSERT:

    INSERT INTO mytable (a,b,c) SELECT 1 a, 2 b, 'x' c 
            UNION ALL SELECT 2, 5, 'y' 
            UNION ALL SELECT 3, 7, 'z' 
           ... 
    
  • 真正的多值INSERT,自SQLite 3.7.11支持:

    INSERT INTO mytable (a,b,c) VALUES (1,2,'x'), 
                (2,5,'y'), 
                (3,7,'z'); 
    
  • 使用事务:

    BEGIN; 
    INSERT INTO mytable (a,b,c) VALUES (1,2,'x'); 
    INSERT INTO mytable (a,b,c) VALUES (2,5,'y'); 
    INSERT INTO mytable (a,b,c) VALUES (3,7,'z'); 
    COMMIT; 
    

如果你问如何将这些目标变为Ruby或Ruby on Rails的 - 我承认,我不知道,但我想它应该是可能的。

但是,即使SQLite不支持这些方法,对于内存中的数据库,这些都不应该真正重要 - 因为如果它实际上全部在内存中,插入速度不应该取决于您是否逐一插入行或作为一项交易。您的速度限制实际上只是原始内存复制带宽。

+0

谢谢,mvp。事实上,事实证明,SQLite支持从3.7.11开始的具有多个值的批量INSERT。 http://www.sqlite.org/changes.html。尽管我怀疑它的工作原理与您的第一个示例差不多 – gmile

+0

当我首先编写我的答案时,我想包括多值插入,因为我可以发誓我成功地使用了它,但是在测试时它不起作用。事实证明,我使用SQLite 3.7.10在盒子上进行了测试。更新的SQLite的确支持多值插入 - 我已经更新了我的答案。 – mvp

0

原来,SQLite支持从3.7.11开始批量插入。