每个产品都有一个 product_date_added
,它是一个包含添加日期的 Date
字段。
它们还有一个 product_views
,它是一个 int
字段,包含产品被查看的次数。
为了按受欢迎程度显示产品,我使用了一种算法来计算产品每天的点击量。
SELECT
AVG(product_views / DATEDIFF(NOW(), product_date_added)) as avg_hits
, product_table.*
FROM product_table
WHERE product_available = "yes"
GROUP BY product_id
ORDER BY avg_hits DESC
这有效,但老板注意到许多旧产品首先出现。所以他基本上希望新的观点比旧的观点有更多的权重。
他的建议是,任何超过一年的观看次数都不算数。我想我必须保留每个 View 的日期才能做到这一点,我认为这会降低性能。
创建我老板要求的流行度算法的最佳方法是什么?
理想情况下,我希望能够提出一些不会改变表结构的东西。如果这是不可能的,我至少想提出一个可以使用现有数据的解决方案,这样我们就不会从 0 开始。如果那也不可能,那么任何可行的方法都行。
最佳答案
您不必(因此)必须保留每个 View 的日期。您可以改为在包含以下列的表中为每个项目保留最多 366 行:product_id、day_of_year、count。每天运行一项任务,将一年前的所有计数归零。如果您不介意非规范化数据,该任务还可以更新项目本身中的“计数”字段以进行快速检索,这样您的查询就不需要更改。 product_views
只是变成 product_views_in_the_last_year
。 1 天的时间段是任意的——我怀疑你是否关心流行度是基于 1 年的窗口,所以我希望它也可以是一个小时、一周或两周,这取决于你有多少桶”重新愿意处理。
另一种方案可能是使用指数衰减。将计数字段转换为十进制类型。每天一次,按固定百分比(小于 1%,大于 0.1%)减少每个项目的计数,以便点击越近,它的“权重”越大。所以老流行永远不会完全消失,但一年前的点击量不会有太大贡献。顺便说一句,与此方案等效的方法是将代码保留原样,但要确保您的网站作为一个整体随着时间的推移而呈指数级流行;-)
至于避免从零开始 - 可能会立即减少每个项目的数量,作为一次性行动,按比例取决于项目的年龄。总体而言,您希望较旧的对象具有较旧的 View ,因此被当前方案高估了。这不是万无一失的,因为也许一些较旧的项目最近获得了很多点击。您可以通过查看最近的 Web 服务器日志或在一次性减少之前花费一周或一个月来计算点击次数来识别这些项目。即使不这样做,如果他们受欢迎是有根本原因的(不仅仅是因为他们目前在你的排名中排名很高,因此从查看你的“最受欢迎”图表的人那里获得了流量),那么希望他们会在给定的时间内恢复.
关于php - 人气,如何让新热比老热更重要?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3753493/