将nokogiri(或任何内部)对象保存到数据库是一个好主意吗?

时间:2013-07-02 04:56:34

标签: ruby-on-rails ruby database blob nokogiri

我在rails上的webapp在XML字符串中存储了一些模型对象的参数,所以每当我需要关于特定对象的一些信息时,我必须解析它的XML字符串。 XML的长度很少超过100行。但是由于我想要优化,我想知道我是否可以将解析后的XML存储为db中的Nokogiri对象。这是个好主意吗?

1 个答案:

答案 0 :(得分:2)

虽然可能存在例外情况,但一般情况下,除非您有非常良好的理由,否则应避免将marshalled objects直接存储在数据库中。在Nokogiri的案例中,由于@ mu-is-too-short mentioned,Nokogiri和Marshal不能很好地合作:

doc = Nokogiri::HTML(some_html)    
Marshal.dump doc
# => TypeError: no _dump_data is defined for class Nokogiri::HTML::Document

也就是说,Marshal#loadMarshal#dump是核心Ruby库的一部分,玩起来非常有趣。在with the docs,这是一个快速代码示例,展示了Marshal的工作原理,包括将Marshal.loadClass.new进行比较的基本基准:

require 'benchmark'

data_string = <<-DATA
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
DATA

class Example
  attr_reader :data

  def initialize(data)
    @data = data
  end
end

example = Example.new(data_string)

dumped = Marshal.dump example
loaded = Marshal.load dumped

puts "String Bytesize: #{data_string.bytesize} vs. Dump Bytesize: #{dumped.bytesize}"
puts "Marshalled object is larger by #{dumped.bytesize - data_string.bytesize} bytes"

Benchmark.bmbm do |x|
  x.report("Marshal.load: ")  { Marshal.load(dumped).data }
  x.report(" Example.new: ")  { Example.new(data_string).data }
end