8

我有兴趣使用这个排名类,根据Evan Miller的一篇文章来对我拥有的有赞成票和反对票的表格进行排名。我有一个非常类似于 Stack Overflow 上/下投票系统的系统,用于我正在开发的活动网站,通过使用这个排名类,我觉得结果会更准确。我的问题是如何按功能“热度”订购?

private function _hotness($upvotes = 0, $downvotes = 0, $posted = 0) {
    $s = $this->_score($upvotes, $downvotes);
    $order = log(max(abs($s), 1), 10);

    if($s > 0) {
        $sign = 1;
    } elseif($s < 0) {
        $sign = -1;
    } else {
        $sign = 0;
    }

    $seconds = $posted - 1134028003;

    return round($order + (($sign * $seconds)/45000), 7);
}

我想每次用户投票时,我都可以在我的表中有一列重新计算新投票的热度数据,并在主页上按该列排序。但我有兴趣在结合上述功能时更即时地执行此操作,我不确定这是否可能。

来自 Evan Miller,他使用:

SELECT widget_id, ((positive + 1.9208) / (positive + negative) - 
                   1.96 * SQRT((positive * negative) / (positive + negative) + 0.9604) / 
                          (positive + negative)) / (1 + 3.8416 / (positive + negative)) 
       AS ci_lower_bound FROM widgets WHERE positive + negative > 0 
       ORDER BY ci_lower_bound DESC;

但我宁愿不在 sql 中进行此计算,因为如果我在多个页面上使用此代码等,我觉得这很混乱且难以更改。

4

3 回答 3

3

访问任何内容(阅读、写作、排序、比较等)的相应“帖子”表非常快,因此依赖数据库是非临时数据存储的“最即时”替代方案(内存/会话仍然更快,但从逻辑上讲,不能用于存储此信息)。

您应该更担心构建一个好的排名算法来提供您想要的结果(您提出两个不同的系统,提供不同的结果)并努力使整个代码和代码-数据库通信尽可能高效。

原则上,具有迭代简单命令的小代码为这种情况提供了最快和最可靠的解决方案。例子:

  1. 每次投票时都会调用排名功能(如您提出的第一个或任何其他建立在您想要的排名规则上的功能)。它写入“帖子”表中的相应列(查询越简单越好:您可以根据需要创建一个复杂的排名系统,但尝试依赖 PHP 而不是查询)。

  2. 每次需要在帖子之间进行比较时,都会使用简单的 SELECT 读取“帖子”表,按排名对记录进行排序(您可以有各种“评估列”(例如,赞成票、反对票、进一步考虑);但是最好有一个具有最终排名的)。

于 2013-06-18T09:45:51.490 回答
1

你是对的,这样的查询也相当混乱和昂贵。

即时混合 PHP/MySQL 是一个坏主意,因为您必须为所有帖子选择值并计算热度,然后选择最热的列表。极其昂贵。

您应该考虑将至少部分计算保存到数据库中。绝对命令应该进入数据库。计算一些东西并在每次保存/更新时只保存一次总是更好,而不是每次显示它时都计算。尝试通过计算保存/更新的顺序而不是每次计算热度来对您将节省多少时间进行基准测试。好消息是订单永远不会改变,除非有人赞成/反对你保存到数据库中的赞成票/反对票,对于标志也是如此。

即使您将符号保存到数据库中,由于发布的时间戳参数,您仍然无法避免即时计算。

我会看看它有什么不同以及它在哪里产生了影响,并且每隔 x 时间使用 CLI 脚本计算热度,仅适用于那些至关重要的脚本,每 y 时间它所产生的影响较小。

采用这种方法,您将仅在必要时重新计算热度。这将使您的应用程序更加高效。

于 2013-06-23T07:37:12.483 回答
0

我不确定您的 DB 和 Schema 是否可行,但是您是否考虑编写用于自定义排序的 UDF?

stackoverflow 的一篇文章讨论了如何在此处执行此操作。

于 2013-06-19T04:27:13.753 回答