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/
精彩评论