使用数据库MySQL(innodb)
相关表设计最大数据量:5000w
假定表news,拥有以下字段:
id int auto_increment,
title varchar(2000) not null default '' comment '标题',
score int not null default 0 comment '基础分值',
visited int not null default 0 comment '展示次数',
voted int not null default 0 comment '投票数',
//hot int not null default 0 comment '热度', 不再作为独立字段,而是在select的时候来计算
created int not null default 0 comment '创建Unix时间戳',
primary key(id),
key score(score),
key visted(visited),
key voted(voted),
key created(created)
其中,hot字段的值是结合visited、voted计算并随着时间衰减的,衰减频率最短为1小时(即间隔1小时就需要根据当前时间戳与created的差值做一次衰减)。数据主要根据hot字段的值来排序展示的,因此需要保证整表hot数据的更新。
另外,我还需要记录一个hot的历史最高值。(补充)hot值有最大限制,不能超过100。
难点:如果独立一个hot字段,数据量大了之后,衰减更新的效率将非常之低并影响系统整体性能;如果另外设一个完全不包含衰减的分数值字段score,需要展示的时候实时再实时计算hot的值又怕SQL执行效率太低。
目前后者的效率肯定更高,不知道各位大神有没有做过类似的需求,有没有更好的方案,求解!
确定在visit和vote操作时更新递增的score值,然后在SELECT列表的时候实时计算经过时间衰减的hot值,对于提取的数据先通过where条件缩小范围,结果进行一定时间的cache缓存。感谢大家!
這種設計有點讓人迷惑,我在想為啥要設計衰減這個操作啊,如果時間因子是
T
的話,完全可以設計類似的公式啊越新的內容
T
一定越大,所以即使他們的visited
和voted
相同,它的hot
值也會大些,如果你不希望時間因子的擾動有這麼大的話也可以這樣hot值只需要一次計算就行了,不需要即時更新,因為你已經把時間因子設計到它裡面了
我會展示的時候再即時計算hot的值,這樣不受一小時的粒度限制,排序可以更即時地變化。
如果效率太低,我就把最後考慮所有因素後產生的結果快取起來。
另:有種暗暗的感覺,題主一定是深受《基於使用者投票的排名演算法》系列文章毒害頗深。
很奇怪的做法,這個hot就不應該和原始資料放到一起,笨一點就用一個專用slave表每小時sql排序一次,徹底一點就單純寫一個模組去隨時更新每個條目的hot值,存到另外一個地方供讀取用。
不好意思,想諮詢一下,您這個排名方式最終的實現方式,本人最近也受到類似問題困擾,感謝您的指導。 。 。謝謝。 。