如何有效地比较用户?

时间:2014-03-10 18:25:12

标签: php mysql comparison performance

我有能够“喜欢”类别的用户。例如,我们可能有2个用户:

John喜欢苹果,橘子,梨

鲍勃喜欢苹果,橘子,馅饼,蛋糕

他们都喜欢苹果,橘子

这对两个用户来说不是问题,但是当我想象将其扩展到成千上万的用户时,会有成千上万的喜欢,会有很大的效率问题。

我需要能够将用户与所有其他用户进行比较,并确定他们的共同点。

我尝试过array_intersect,但它没有扩展。我需要一个mysql解决方案。

我如何有效地返回分享相同喜欢的用户以及共享的喜欢的用户?

users
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| name  | varchar(16) | NO   |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+

categories
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| name  | varchar(32) | NO   |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+

likes
+-------------+---------+------+-----+---------+-------+
| Field       | Type    | Null | Key | Default | Extra |
+-------------+---------+------+-----+---------+-------+
| user_id     | int(11) | NO   | MUL | NULL    |       |
| category_id | int(11) | NO   | MUL | NULL    |       |
+-------------+---------+------+-----+---------+-------+

2 个答案:

答案 0 :(得分:0)

function find_intersect($likes1, $likes2){

    sort($likes1);
    sort($likes2);

    $intersect = array();

    $i = 0;
    $j = 0;

    while ($i < count($likes1) and $j < count($likes2)){
        if ($likes1[$i] == $likes2[$j]){
            array_push($intersect, $likes1[$i]);
            $i++;
            $j++;
            }
        else if ($likes1[$i] < $likes2[$j])
            $i++;
        else
            $j++;
    }

    return $intersect;
}

上面是我鼓起来的,它应该是找到两个数组相交的最有效方法。我同意@DanFarrell,但是当涉及到成千上万的用户时,MySQL或某些数据库在管理信息方面会更有效率。

答案 1 :(得分:0)

我能用以下方法解决我的问题:

SELECT user_id, count(category_id) AS count, group_concat(category_id separator "|")
FROM likes
WHERE category_id IN (
    SELECT category_id
    FROM likes
    WHERE user_id=1
)
AND user_id != 1
GROUP BY user_id;

这将返回用户ID,共享的类别数量以及由管道字符分隔的共享项目。显然,它需要连接来获取用户名和类别,但为了简单/可读性,我把它们排除了。