在Rails应用中跟踪统计信息的最佳方式是什么?

时间:2018-04-11 19:32:38

标签: ruby-on-rails database postgresql

我有一个Ruby on Rails应用程序,这是一种游戏。有一个用户模型,每个用户有大约10个属性,每个属性有大约10个可能的值。用户使用通过或失败布尔值对其他用户进行评级。我希望每次用户被评为通过时跟踪统计数据。因此,为每个用户提供他们所传递的属性的标签,以及将他们评为通行证的属性。我想要一个统计页面,用户可以看到10个属性中的每一个,以及每个属性值的计数,包括他们通过的人员以及通过他们的人员。

我提出的是一个名为Stat的模型,其中包含与用户的belongs_to / has_one关联。

# app/models/user.rb
has_one :stat

# app/models/stat.rb
belongs_to :user

统计信息表为每个用户和user_id字段都有一行。然后,对于用户的评价者和用户评价者(100 x 2)时,每个用户的10个属性(因此100个字段)的10个可能选项中的每一个都有整数字段。这总共有201个领域,看起来非常多。当用户通过另一个用户时,对于每个传递的用户的属性值,将1添加到评估者行的统计表中,并为每个评估者的属性值添加1到ratee的行。

每个用户都有一个统计信息页面,显示他们通过的10个属性中的每个属性的10个可能值中的每个值,并分别为谁传递它们。

我的问题是,一个包含201个字段的大型统计表是设置它的最佳方式。我试着把它分成两个表,一个用于rater,一个用于ratee,但设置似乎只是增加了更多的复杂性。有没有更好的方法,我没有看到这样做?

2 个答案:

答案 0 :(得分:0)

你的直觉是正确的。想象一下,如果你添加了一个新的属性来跟踪,你必须做的工作?您必须编写另一个迁移。

我建议使用连接表来跟踪正在评估的用户,作为评估者的用户,stat_id和分数。这还需要统计表。

class Stat < ActiveRecord::Base
  validates_presence_of :name
end

class UserStatRating < ActiveRecord::Base
  belongs_to :user
  belongs_to :evaluator, class_name: 'User'
  belongs_to :stat

  validates_presence_of :score
end

class User < ActiveRecord::Base
  has_many :user_stat_ratings, dependent: :destroy
end

使用此方法,您可以在路上Stat.create(name: 'new stat')创建更多统计信息,而无需更改架构。

答案 1 :(得分:0)

拥有200多列的表几乎是最容易想到的解决方案。

经典的方式

&#34;经典&#34;这样做的方法是创建一个键/值表:

class CreateStats < ActiveRecord::Migration[5.0]
  def change
    create_table :attributes do |t|
      t.string :key
    end
    add_index :attributes, :key
  end
end

class CreateUserStats < ActiveRecord::Migration[5.0]
  def change
    create_table :user_stats do |t|
      t.belongs_to :user, foreign_key: true
      t.belongs_to :attribute, foreign_key: true
      t.boolean :value

      t.timestamps
    end
    add_index :stats, [:key_id, :user_id]
  end
end

class Stat < ApplicationRecord
  has_many :user_attributes
end

class UserStat < ApplicationRecord
  belongs_to :user
  belongs_to :stat
  delegate :key, to: :stat
end

另一种变体是您可以在主表中存储可用键以提供数据规范化:

class UserStat < ApplicationRecord
  belongs_to :user
  belongs_to :stat
  has_many :stat_reviews
  delegate :key, to: :stat
end

class StatReview < ApplicationRecord
  belongs_to :user_stat
  belongs_to :reviewer, class_name: :user
end

(+)它是一个常规的关系表,因此您可以使用ActiveRecord关联将UserAttributes链接到某种评级。

{{1}}

( - )一个列在关系数据库中只能有一个类型。这通常意味着您必须使用字符串列并在应用程序中键入强制转换值。

HSTORE,JSON和JSONB

Postgres现在有其他数据类型,如HSTORE,JSON和JSONB,可用于存储任意键/值类型数据结构。

(+)无类型/无模式,因此您可以使用您想要的任何类型的值。

( - )非关系,所以你不能使用关联。