PHP怎样按热度排序视频列表_PHP按热度排序视频列表方法【排序】

合理热度值设计需引入时间衰减因子,如hot_score = play_count * POW(0.98, DATEDIFF(NOW(), created_at)),并配合索引、预计算、Redis缓存ID列表及游标分页保障性能与稳定性。

php怎样按热度排序视频列表_php按热度排序视频列表方法【排序】

热度值怎么设计才合理

直接用播放量 play_count 排序会出问题:一个 5 年前的老视频可能有 100 万播放,但最近一周没人看;而一个新视频 24 小时内涨了 5 万播放,实际热度更高。所以得加时间衰减因子。

常见做法是用「加权热度」公式,比如:
hot_score = play_count / (1 + days_since_created * 0.3)
或者更平滑的指数衰减:
hot_score = play_count * pow(0.98, days_since_created)

  • 别用纯整数除法(如 play_count / days),PHP 里 7 / 32.333...,但若字段类型是 INT 且没显式转 FLOAT,MySQL 可能截断
  • 如果视频表没有 created_at 字段,先补上:ALTER TABLE videos ADD COLUMN created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
  • 避免在 ORDER BY 里写复杂表达式(如 LOG(play_count + 1) * EXP(-HOUR(NOW() - created_at)/720)),会拖慢查询、无法走索引

SQL 层直接排序最省资源

除非业务要求实时动态算分(比如叠加点赞、分享、完播率),否则优先在数据库层完成排序。PHP 只负责取数据,不自己 usort() 整个列表——10 万条记录全拉到 PHP 再排,内存和时间都爆炸。

SELECT id, title, play_count, created_at,
       play_count * POW(0.98, DATEDIFF(NOW(), created_at)) AS hot_score
FROM videos
WHERE status = 'published'
ORDER BY hot_score DESC
LIMIT 20;
  • POW() 在 MySQL 5.7+ 和 MariaDB 10.2+ 支持;低版本可用 POWER() 替代
  • 务必给 status 加索引,否则 WHERE 先全表扫描
  • 如果还要支持「按周热度」「按日热度」切换,别用 CASE WHEN 套大表达式,建议拆成不同 SQL 或加预计算列(如 week_hot_score

PHP 侧缓存与更新策略

热度排序结果变化没那么快,每小时更新一次足够。硬扛实时请求,数据库压力大,用户也感知不到毫秒级差异。

  • 用 Redis 缓存排序 ID 列表:$redis->zRevRange('video:hot:weekly', 0, 19),配合 ZADD 每小时批量更新
  • 不要缓存完整视频数据(含封面 URL、描述等),只缓存 id 序列,查出来再 IN () 查详情——避免缓存膨胀和数据不一致
  • 如果某视频突然爆火(比如被大 V 转发),加个轻量钩子:检测 play_count 单小时增长 > 5000,就触发该条目的 hot_score 强制重算并刷新缓存

注意分页时的稳定性

ORDER BY hot_score DESC LIMIT 20 OFFSET 40 分页,在高并发下容易漏数据或重复——因为热度值随时间浮动,第 3 页加载时,第 1 页的新进视频可能把原第 41 名挤掉,导致翻页错位。

LAIKA

LAIKA

LAIKA 是一个创意伙伴,您可以训练它像您(或您想要的任何人)一样写作。

下载

立即学习PHP免费学习笔记(深入)”;

  • 改用游标分页:记住上一页最后一条的 hot_scoreid,下一页查 WHERE hot_score
  • 如果必须用 OFFSET,至少加 hot_score 的冗余索引:ALTER TABLE videos ADD INDEX idx_hot_status (status, hot_score DESC, id)
  • 前端展示“热度榜”时,别显示精确到小数点后 6 位的 hot_score——用户不需要,还暴露算法细节

真实场景里,最难的不是写对那条 ORDER BY,而是定义清楚「热度」到底服务什么目标:是推新?促长尾?还是承接突发流量?这些决定了衰减系数、是否加入互动权重、要不要人工置顶干预。算法可以调,但目标模糊,越调越乱。

https://www.php.cn/faq/1989502.html

发表回复

Your email address will not be published. Required fields are marked *