开发者

How would you represent the following data set on the Model layer in an MVC application?

        Foreign Direct Investment (% GDP)   


            2000    2001    2002    2003    2004    2005    2006
Brazil    5.09    4.05    3.28    1.84    2.74    1.7     1.73      
China      3.22    3.36    3.39    2.86    2.84    3.44    2.81     
India      0.78    1.15    1.11    0.73    0.83    0.94    2.13     
Mexico    2.87    4.43    3.37    2.35    3.11    2.57    2.01

I have 2 ideas for my Ruby on Rails application:

1) Have 3 models:

  • MetricType will contain the type of metric (FDI) and will have many DataPoint objects
  • DataPoint will have a value and year and will belong to one Country object and one MetricType object
  • A Country object will also have many DataPoint objects (representing a row)

2) Less normalized but maybe more efficient for handling lots of data

  • MetricType will contain the type of metric (FDI) and will have many DataSet objects
  • DataSet will belong to one MetricType and one Country object
  • DataSet will have an array of hashes to represent values - [{"year" 开发者_如何转开发=> "value"},{"year" => "value"},...]

Are these both good methods for abstracting the data? Which would you use or would you propose an alternate method?

Thanks!


It depends on how dynamic you want your system to be. You could do it simply with one class (and db table) per metric type and associate them via Country.has_many :foreign_direct_investment_metrics, etc (easier).

Or you could go more dynamic, I would use Single Table Inheritance on Metrics, like this:

class Country < ActiveRecord::Base
  has_many :data_points, :class_name => 'Metric'
  has_many :foreign_direct_investments, :class_name => 'ForeignDirectInvestment'
end

class Metric < ActiveRecord::Base
  belongs_to :country
end

class ForeignDirectInvestment < Metric
end

class OtherMetricType < Metric
end

# c = Country.new(:name => 'Brazil')
# c.data_points << ForeignDirectInvestment.new(:year => 2000, :value => 5.09)
# c.save

And your db schema:

  create_table "countries", :force => true do |t|
    t.string   "name"
    t.datetime "created_at"
    t.datetime "updated_at"
  end   

  create_table "metrics", :force => true do |t|
    t.integer  "country_id"
    t.string   "type"
    t.integer  "year"
    t.float    "value"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

This lets you add methods to ForeignDirectInvestment while keeping you flexible for recording more metrics. ActiveRecord's STI does have caveats, though, such as all your keys for all your models have to go on the base metrics table. There's a good intro to STI here: http://juixe.com/techknow/index.php/2006/06/03/rails-single-table-inheritance/

You might also want to consider a document db like MongoDb. MongoMapper is a simple data mapper for Mongo and Rails, and it makes solving these kinds of problems easier too. See http://mongomapper.com/

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜