Sqlite vs基于文件的数据存储?

时间:2011-05-03 12:10:43

标签: ruby

说我喜欢这样的课程:

class User
  attr_accessor :name, :age
  def initialize(name, age)
    @name, @age = name, age
  end
end

现在,将用户保存为单个文件中的用户类的封送实例或将Sqlite数据库与ORM一起使用会更快吗?基于文件的数据存储有哪些缺点?

4 个答案:

答案 0 :(得分:4)

以下是在SSD上执行的基准测试的结果。像你一样解释它们。对于非常简单的查询和数据,将整个数据集编组并加载到内存中的速度更快:

Rehearsal ---------------------------------------------------------------
Storing in DB                 0.080000   0.000000   0.080000 (  0.085909)
Marshalling to Disk           0.010000   0.000000   0.010000 (  0.004340)
Fetching marshal              0.000000   0.000000   0.000000 (  0.002288)
Fetching records from DB      5.530000   0.130000   5.660000 (  5.657053)
Fetching records from Array   0.350000   0.000000   0.350000 (  0.347798)
Find one record from DB       0.320000   0.020000   0.340000 (  0.336068)
Find one record from Array    0.260000   0.000000   0.260000 (  0.258766)
------------------------------------------------------ total: 6.700000sec

                                  user     system      total        real
Storing in DB                 0.080000   0.000000   0.080000 (  0.079717)
Marshalling to Disk           0.000000   0.000000   0.000000 (  0.002595)
Fetching marshal              0.000000   0.000000   0.000000 (  0.001466)
Fetching records from DB     10.830000   0.230000  11.060000 ( 11.041669)
Fetching records from Array   0.340000   0.000000   0.340000 (  0.335473)
Find one record from DB       0.320000   0.010000   0.330000 (  0.336917)
Find one record from Array    0.260000   0.000000   0.260000 (  0.255746)

这是基准:

require 'benchmark'
require 'sequel'
class User
  attr_reader :name, :age
  def initialize(name, age)
    @name, @age = name, age
  end
  def to_hash; {name:@name, age:@age}; end
end
db_array = 1000.times.map{ User.new "name#{rand 1000}", rand(1000) }
db_array << User.new( "unique", 42 )
DBFILE  = 'users.db'; MARSHAL = 'users.marshal'
File.delete(DBFILE) if File.exists?(DBFILE)
DB = Sequel.sqlite(DBFILE)
DB.create_table(:users){ column(:name,:string); column(:age,:int) }
db_users = DB[:users]
Benchmark.bmbm do |x|
  x.report('Storing in DB'){ db_users.multi_insert db_array.map(&:to_hash) }
  x.report('Marshalling to Disk'){ File.open(MARSHAL, 'w'){ |f| f << Marshal.dump(db_array) } }
  x.report('Fetching marshal'){ db_array = Marshal.load(File.open(MARSHAL,'r'){|f| f.read }) }
  query = db_users.select{ name > "name500" }
  x.report('Fetching records from DB'){ 1000.times{ query.all } }
  x.report('Fetching records from Array'){ 1000.times{ db_array.select{ |u| u.name > "name500" } } }
  x.report('Find one record from DB'){ 1000.times{ db_users[name:'unique'] } }
  x.report('Find one record from Array'){ 1000.times{ db_array.find{ |u| u.name == "unique" } } }
end

答案 1 :(得分:3)

存储编组对象的缺点是,您编组的数据可能与以后对ruby类的更改不兼容。因此,您最终可能会将Hash或Array等基本结构保存到文件中。如果您在那时,使用SQLite是更好的选择。

答案 2 :(得分:2)

我认为这取决于你想要做什么操作:如果你只想从文件中读取所有内容,而不执行搜索/选择单个实例和类似的东西,使用文件更好(你只需阅读它和重建实例)。

如果您希望任何类型的访问不同于级联读取,请使用数据库(它们是程序优化的,以尽可能快地写入/读取文件,允许该类型的操作;)

还有另外一个小问题需要考虑:我不知道ruby如何执行和处理文件(因为解析器可能从文件读取速度较慢),我想你可以在ruby论坛上问这个,但我想读一个文件从头到尾都不会有问题

答案 3 :(得分:0)

我会将SQLite与DataMapper ORM(http://datamapper.org/)一起使用。

我认为将用户存储在单个文件中很难管理。使用DataMapper查询SQLite数据库非常简单。