Web应用程序将用于用户来自不同类别的不同帖子。
例如,类别可以是"幽默"、"体育"等。
所以为此,我将有简单的表格:Categories(id, category_name)
。
次数,因此下次用户登录时,他的默认页面将是包含用户访问最多的两个不同类别的帖子的页面。
对此的基本想法(我将使用Ruby on Rails),在控制器提供某些页面之前,该类别的计数器将递增并保存到数据库中。我的问题是我不知道在哪里保存这个类别的计数器?
第一个想法(表格计数器):
Counters(id, category_name1, category_name2, ..., category_nameN, user_id)
其中category_name是整数字段表示用户访问次数(特定类别)。这个想法不好,因为当我添加新类别时,我必须更改此表以添加新列。
第二个想法:
Counters(id, count, category_id, user_id)
对我来说,更好的主意,但我想仍然不是很好的性能,因为每个用户我将有 N 行,其中 N 是类别数。因此,如果我有 1000 个用户和 10 个类别,那将是过度杀伤力?
用户 * 10 个类别 = 10000 行,这在数据库世界中绝不被认为是"大"的。
除非客户端库另有强制要求,否则应使用自然键设计:
Counter(user_id, category_id, count, PRIMARY KEY (user_id, category_id))
如果您的 DBMS 支持聚类,则整个表可以在物理上表示为单个 B 树,这对于查询、修改和缓存非常有效。
话虽如此,你确定你需要永恒的计数吗?也许最好只保留过去 30 天的计数1?这将需要:1000 个用户 * 10 个类别 * 30 天 = 300000 行,这仍然不是特别"大"。
或者,您可以运行一个定期批处理作业,将所有计数乘以小于 1 的某个因子(例如 0.9),这将使旧访问不如新访问"重要"。在这种情况下,您可能希望对计数器使用一些浮点类型(而不是整数)。
1 或 90 或其他什么...
对于该卷,我将使用第二种方法 -
Counters(id, count, category_id, user_id)
除非您遇到性能问题,然后才切换到其他方法。
您还可以使用计数器缓存来帮助解决此问题:
http://guides.rubyonrails.org/association_basics.html#detailed-association-reference
例如
class Counter < ActiveRecord::Base
belongs_to :category, dependent: :destroy,
counter_cache: true
end
与 Rails 一样,最好在离开轨道之前先开始。