我有能够“喜欢”类别的用户。例如,我们可能有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 | |
+-------------+---------+------+-----+---------+-------+
答案 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,共享的类别数量以及由管道字符分隔的共享项目。显然,它需要连接来获取用户名和类别,但为了简单/可读性,我把它们排除了。