gpt4 book ai didi

mysql - 显示按 "on the fly score calculation"排序的带分页的文章的最佳做法是什么

转载 作者:行者123 更新时间:2023-11-29 03:28:07 25 4
gpt4 key购买 nike

我必须分页并显示大量按“分数”排序的文章,这个分数不会保存在任何地方,而是在页面加载时计算。

文章的评分取决于很多因素,比如点击率、分享率、点赞数、收藏夹,我的意思是我不能把逻辑放在 SQL 查询中。

所以,我所做的是:获取完整数据 -> 计算所有数据的分数 -> 按最高分数排序 -> 显示为数组 block (使用 Laravel 自定义分页器)


$Articles =  DB::table('articles')->get();

//for test purpose here i can run a for-loop and print its values

foreach ($Articles as $Article) {
echo "Article id : ".$Article->id";
//here i cant print $Article->score
}

$Articles = $this->likesScoreFunction1($Articles);
$Articles = $this->scorefunction2($Articles);
$Articles = $this->scorefunction3($Articles);

我在 scoreFunctions 中所做的是添加一个名称为“score”的额外数组值,以及使用最新分数更新下一个函数等等。我的意思是在这些测试函数之后,我可以运行一个 for 循环,如下所示:

foreach ($Article as $Article) {
echo "Article id : ".$Article->id." score is ".$Article->score."\n";
}

usort($Articles, function($a, $b) {
return $b['score'] - $a['score'];
});

最后,我在 $Articles;

找到了按分数排序的文章

然后我将第一个数组 block 传递给 View 。

我知道这不是一个好方法,因为我将所有文章的值加载到内存中。任何人都可以为此推荐任何更好的方法吗?

The score can be different at different minutes or seconds..

一种可能性是每分钟运行一次 cron 并更新分数字段。这是不切实际的,因为这会处理系统中所有组织的所有文章。

我的客户不想采用上述方法,因为当任何用户发布一篇文章时,它的得分最高,应该排在首位。在 cron 完成它的工作之前,我们不会在顶部看到新文章。

最佳答案

几周前我遇到了一个复杂排名算法的类似问题,并尝试了您描述的各种方法。

Pure SQL 难以调试和维护,而且执行起来很慢。数据库必须选择所有文章,加入所有相关的投票/分数/等,对整个集合进行排序然后返回分页结果。在某些情况下,它不能为此使用索引。数据库缓存中充满了(对我而言)不相关的记录。

纯SQL版本应用了前端缓存。我们无法找到合适的缓存年龄 - 要么是等级过时,要么是太多请求缺少缓存。

未尝试使用

SQL 和 PHP 进行实时计算。我认为它只能比纯 SQL 方法慢。

为了及时获得结果,我们必须提前存储计算出的排名值。正如您已经在探索的那样,有几种方法可以实现它;

  • 将整个目录重新计算为 cron 作业 - 如您所知,这太慢了,太慢了
  • 事件监听器事件 发生时(投票、社交分享等)重新计算特定文章的排名 - 我们使用它效果很好,但是在我们的场景中,太多的事件导致了太多的同时计算
  • 事件队列 跟踪所有最近发生的事件。进程或 cron 作业重新计算队列中当前事件最多的文章的排名,从而消除最可能排队的作业并使用 CPU 周期以达到最大效果。

事件队列对我们有用,所以我不再寻找其他解决方案。我们确实用 Varnish 添加了一个 1-3 秒的微缓存来减轻数据库的流量负担,以确保实时工作和排名计算之间的良好平衡。

SQL 在基于时间的计算方面仍然很好,例如,我不希望在文章上触发常规事件以随着时间的推移降低排名。如果排名是事件和时间的组合,我会存储预先计算的基于事件的排名、发布时间,并让 SQL 查询计算组合。

当我们的排名变得如此复杂时,我们使用了一个单独的表,纯粹用于排名(固定宽度的数据列,巧妙的索引),与文章具有一对一的关系。或者如果用户可以选择如何对它们进行排名,则为多对一关系。这样,数据库就不需要每次都加载所有文章数据并搜索低效索引。只需在排名分页后加入文章数据即可。

如果您正在使用 Doctrine,请注意贪婪的水合作用。

喂!

关于mysql - 显示按 "on the fly score calculation"排序的带分页的文章的最佳做法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33689504/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com