两个结果集之间的相似性比较(Compare similarities between two res

2019-06-25 08:00发布

我创建一个音乐网站,我希望用户能够找到谁喜欢大致相同的艺术家,因为他们的用户。

我有一个“喜欢”表有两列“id_user”,“id_artist”。 下面是我怎么想它的工作的例子:

User 1 likes:
1, 12
1, 13
1, 14
1, 26
1, 42
1, 44

User 2 likes:
2, 13
2, 14
2, 15
2, 26
2, 42
2, 56

这些用户的共同点4名艺术家。 有没有一种方法,来比较这些2个的结果集,要在数据库中找到最相似的人呢?

我的第一个想法是串联喜欢以这种方式:“12,13,14,26,42,44”,在一个字符串,并使用MySQL全文索引分数来比较不同的字符串。 没有工作......不知道为什么,但MySQL全文索引只能用文字作品...不能与数字...

任何想法或任何线索将不胜感激。

Answer 1:

事情是这样的:

SELECT first_user.id_user, second_user.id_user, COUNT(first_user.id_user) AS total_matches

FROM likes AS first_user

JOIN likes AS second_user
ON second_user.id_artist = first_user.id_artist
AND second_user.id_user != first_user.id_user

GROUP BY first_user.id_user, second_user.id_user

ORDER BY total_matches DESC

LIMIT 1

请注意,这不是很有效。 来解决此的一种方法是使一个“高速缓存表的”包含该查询的输出与LIMIT 1移除部分。 添加一些相关的指标做查询该缓存表。 您可以设置一个cron作业来定期更新该表。

例:

CREATE TABLE IF NOT EXISTS `likes` (
  `id_user` varchar(50) DEFAULT NULL,
  `id_artist` varchar(50) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `likes` (`id_user`, `id_artist`) VALUES ('8', '39'), ('8', '37'), ('4', '37'), ('8', '24'), ('8', '7'), ('4', '28'), ('8', '28'), ('4', '27'), ('4', '11'), ('8', '49'), ('4', '7'), ('4', '40'), ('4', '29'), ('8', '22'), ('4', '29'), ('8', '11'), ('8', '28'), ('4', '7'), ('4', '31'), ('8', '42'), ('8', '25'), ('4', '25'), ('4', '17'), ('4', '32'), ('4', '46'), ('4', '19'), ('8', '34'), ('3', '32'), ('4', '21')

+---------+---------+---------------+
| id_user | id_user | total_matches |
+---------+---------+---------------+
| 8       | 4       |             7 |
+---------+---------+---------------+


Answer 2:

有可能加入表本身。 (您需要指定一个别名为表的两个“拷贝”中的至少一个,让你的查询是不明确的。)

所以,有了两个用户,则可以通过做加盟的发现“喜欢”他们的共同点like表本身。 您还可以找到哪些用户1的喜好的比例由用户2做左连接两者多少结果有计算,有多少是空的共享。 请注意,这不是一个对称操作,你将需要解决,其中数字的一个或两个是0的情况下。

当你说你要“在数据库中找到最相似的人”:你可以为每对用户做到这一点,但要注意,如果你有n用户,那么这涉及到做n*(n-1)/2的比较,这是的量级n平方。 这可能是相当多的工作,为你的数据库,如果你有很多用户要做。



文章来源: Compare similarities between two result sets