我怎样才能有效地存储双向"喜欢"系统类似于Tinder?

时间:2015-04-10 02:28:53

标签: mysql sql database indexing

在Tinder上,当2个成员彼此喜欢时,他们是“匹配”并且能够进行交流。如果只有一个成员喜欢另一个成员,那么这不是匹配。

我正在尝试在MySQL中存储这个“Like”系统,但无法找到最有效的方法。这是我现在的设置。

mysql> desc likes_likes;
+--------------+----------+------+-----+---------+----------------+
| Field        | Type     | Null | Key | Default | Extra          |
+--------------+----------+------+-----+---------+----------------+
| id           | int(11)  | NO   | PRI | NULL    | auto_increment |
| from_user_id | int(11)  | NO   | MUL | NULL    |                |
| to_user_id   | int(11)  | NO   | MUL | NULL    |                |
| value        | int(11)  | NO   |     | NULL    |                |
| created_at   | datetime | NO   |     | NULL    |                |
| updated_at   | datetime | YES  |     | NULL    |                |
+--------------+----------+------+-----+---------+----------------+
6 rows in set (0.00 sec)

要查找我的比赛,我会查询类似......

SELECT to_user_id FROM likes_likes WHERE from_user_id = my_id AND value = 1 AND .... I don't know how to join the same table from here.

如何在此表上执行查询?如果效率不高,那么存储这个模型的更好的结构是什么?

1就像,0不一样。这是唯一的2个值。

5 个答案:

答案 0 :(得分:2)

SELECT A.from_user_id AS userA, B.from_user_id AS userB
FROM likes_likes A
JOIN likes_likes B
  ON A.from_user_id = B.to_user_id
  AND A.to_user_id = B.from_user_id
  AND A.id <> B.id
WHERE A.value = 1
  AND B.value = 1

答案 1 :(得分:1)

要查找匹配项,您可以使用带别名的常规联接:

SELECT l1.from_user_id user1, l2.from_user_id user2
FROM likes_likes l1
INNER JOIN likes_likes l2 ON
  l2.from_user_id = l1.to_user_id AND
  l1.to_user_id = l2.from_user_id AND
  l1.value = 1 AND l2.value = 1

第一个条件会检查user1个人是否喜欢user2user2是否喜欢至少一个其他人。

第二个条件完成了检查,以便我们现在有两个人相互表达了意见。

最后两次检查确保他们彼此都喜欢:)

答案 2 :(得分:1)

以下是使用group by least(),greatest()将每个唯一用户组合成一个组,然后检查每个组是否有2行

的方法
select least(from_user_id,to_user_id), greatest(from_user_id,to_user_id)
from likes_likes
where value = 1
-- and my_id in (from_user_id,to_user_id)
group by least(from_user_id,to_user_id), greatest(from_user_id,to_user_id)
having count(*) = 2

如果可能有多个喜欢从同一个用户到另一个用户(即用户&#39; A&#39;喜欢用户&#39; B&#39;两次),那么请使用{{1} }

答案 3 :(得分:0)

你真的需要value吗?如果没有行就没有。在此查询中,您应该获得匹配的10的相互匹配。

SELECT 
  COUNT(*) 
FROM 
  likes_like i_like_you
 JOIN likes_like you_like_me ON i_like_you.to_user_id = you_like_me.from_user_id
WHERE 
  i_like_you.from_user_id = @my_id
  AND you_like_me.from_user_id = @your_id

答案 4 :(得分:0)

id有什么理由吗?看起来这对(from_user_idto_user_id)应该是独一无二的,因此可能是'自然'PRIMARY KEY

我还没有看到任何需要value的好论据。

因此该表缩小为

CREATE TABLE likes_likes (
    from_user_id ...,
    to_user_id ...,
    created_at ...,
    updated_at ...,
    PRIMARY KEY(from_user_id, to_user_id), -- serves as the necessary INDEX.
) ENGINE=InnoDB;

SELECT  A.from_user_id AS userA,
        B.from_user_id AS userB
    FROM  likes_likes A
    JOIN  likes_likes B
         ON  A.from_user_id = B.to_user_id
        AND  A.to_user_id = B.from_user_id

(我假设你不允许一个人喜欢自己。)