Sqlite vs基于文件的数据存储?
说我喜欢这样的课程:
class User attr_accessor :name, :age def initialize(name, age) @name, @age = name, age end end
现在,将用户保存为单个文件中的User类的封送实例或将Sqlite数据库与ORM一起使用会更快吗? 基于文件的数据存储有哪些缺点?
以下是在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
存储编组对象的缺点是,您的编组数据可能与将来对ruby类的更改不兼容。 因此,您可能最终会将Hash或Array等基本结构保存到文件中。 如果您在那时,使用SQLite是更好的选择。
我认为这取决于你想要做什么操作:如果你只想从文件中读取所有内容,而不执行搜索/选择单个实例和类似的东西,使用文件更好(你只需阅读它并重建实例) 。
如果您想要任何类型的访问不同于级联读取,请使用数据库(它们是程序优化的,以尽可能快地写入/读取文件,允许该类型的操作;))
还有一个小问题要考虑:我不知道ruby如何执行和处理文件(因为解析器可能从文件读取速度较慢),我想你可以在ruby论坛上问这个,但我想从头开始读文件结束不会有问题
我会将SQLite与DataMapper ORM( http://datamapper.org/ )一起使用。
我认为将用户存储在单个文件中将很难管理。 使用DataMapper查询SQLite数据库非常简单。