Sqlite vs Файловое хранилище данных? - PullRequest
3 голосов
/ 03 мая 2011

Скажем, у меня есть класс, похожий на этот:

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

Теперь, будет ли быстрее сохранить пользователей как маршалированные экземпляры класса User в отдельных файлах или использовать базу данных Sqlite с ORM? Каковы недостатки файлового хранилища данных?

Ответы [ 4 ]

4 голосов
/ 03 мая 2011

Вот результаты теста производительности 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
3 голосов
/ 03 мая 2011

Хранение маршаллированных объектов имеет тот недостаток, что ваши маршаллированные данные могут быть несовместимы с будущими изменениями в классе ruby.Таким образом, вы, вероятно, в конечном итоге сохраните базовые структуры, такие как Hash или Array, в файлы.Если вы находитесь на этом этапе, лучше использовать SQLite.

2 голосов
/ 03 мая 2011

Я думаю, что это зависит от того, какие операции вы хотели бы выполнить: если вы хотите просто прочитать все из файла, без выполнения поиска / выбора одного экземпляра и тому подобного, лучше использовать файл (вам просто нужно прочитать его и восстановить экземпляры).

Если вам нужен какой-либо тип доступа, отличный от каскадного чтения, используйте базу данных (они оптимизированы программой для записи / чтения файла настолько быстро, насколько это возможно, позволяя также операции такого типа;))

Есть еще одна маленькая проблема: я не знаю, как ruby ​​выполняет и обрабатывает файл (возможно, чтение из файла медленнее из-за синтаксического анализатора), я думаю, вы можете задать это на форуме ruby, но я полагаю, что чтение файл от начала до конца не будет проблемой

0 голосов
/ 03 мая 2011

Я бы использовал SQLite с DataMapper ORM (http://datamapper.org/).

Я думаю, что хранить ваших пользователей в отдельном файле будет сложно.Запрос к базе данных SQLite с помощью DataMapper очень прост.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...