我正在构建类似于Tinder的功能。人们可以“喜欢”或“跳过”其他人的照片,如果两个人“彼此喜欢”那么就会有匹配。
此功能的数据库结构的最佳方法是什么?我希望能够获得所有比赛的列表以及每个人的所有比赛。
方法1:
Person | JudgedPerson | Like
------ | ------------ | ----
1 | 2 | yes
2 | 1 | yes
1 | 3 | yes
3 | 1 | no
2 | 3 | yes
这看起来像是一种逻辑方法,但很难创建MySql查询来发现匹配。或者有一种简单的方法可以发现它吗?
方法2
Person1 | Person2 | P1LikesP2 | P2LikesP1
------- | ------- | --------- | ---------
1 | 2 | yes | yes
1 | 3 | yes | no
2 | 3 | yes | null
创建查询以获得匹配很容易,但数据模型可能不是最好的。
最好的方法是什么? 如果方法1是最好的方法,我可以用什么mysql查询来发现匹配?
答案 0 :(得分:5)
我没有正式理由说明为什么我更喜欢第一种选择,但显然第二种选择并未完全正常化。
要查询第一个表并找到彼此喜欢的人,您可以尝试以下自我加入:
SELECT DISTINCT LEAST(t1.Person, t1.JudgedPerson) AS Person1,
GREATEST(t1.Person, t1.JudgedPerson) AS Person2
FROM yourTable t1
INNER JOIN yourTable t2
ON t1.JudgedPerson = t2.Person AND
t1.Person = t2.JudgedPerson
WHERE t1.Like = 'yes' AND
t2.Like = 'yes'
注意:我将DISTINCT
以及LEAST
/ GREATEST
添加到SELECT
子句中,因为每次匹配实际上都会以重复的形式出现。其原因在于,例如, <{1}}将是一个匹配的记录,但1 -> 2, 2 -> 1
也将是第二个记录。
答案 1 :(得分:0)
就个人而言,我会考虑为所提出的选项添加另一个选项:拥有2个表 - 喜欢和匹配:
<强>匹配强>
Person1 | Person2
------ | --------
1 | 2
1 | 3
2 | 1
3 | 1
<强>喜欢强>
Who | Whom | Likes
--- | -----|---------
2 | 3 | 'no'
获得匹配将是一个简单的查询:
SELECT p.*
FROM Persons p
INNER JOIN Matches m ON p.Id = m.Person2
WHERE m.Person1 = @judgedPersonId
这个想法是预先计算匹配而不是在每个查询上解析它们(在后台进程或类似操作期间 - 删除双向喜欢并向匹配表添加记录)。
这样,在选择匹配时,查询会变得更快更轻松,但这种方法涉及额外的复杂性计算“匹配”并进行相关查询(例如,找到尚未匹配且不喜欢的人)。