繁体   English   中英

适用于Tinder的高效MySQL数据库设计

[英]Efficient MySQL database design for a Tinder like app

我正在创建一个像Tinder这样的应用程序。 哪个用户可以向右滑动或向左滑动或向左滑动或不喜欢其他用户。 问题是关于存储用户的操作。 用户操作需要一个表,如下所示

Person 1.   |   Person 2.    |     op
__________________________________
000001.          000007.          Dislike
000001.          000011.          Like
000001.          000053.          Dislike
000001.          000173.          Dislike

它存储操作并且还用于不向用户显示更多次。 到现在为止还可以。

但问题是,如果只有1000个用户刷了另外1000个用户,那么该表将有1M行。 如果100,000个用户这样做......那就是100M的行! 这是非常巨大的。

你们有没有想过一个不会变得那么大的结构设计?

谢谢。

你将永远不会有1M行,因为如果你正在做一个类似Tinder的应用程序,你可以重新匹配人。 因此,我建议您添加一个日期列,以了解何时可以删除行和存储过程,以便清除过期关系。

使用此列,行不会堆叠,您将永远不会有数百万行。

当人们喜欢在一起时,你也不需要存储。

编辑:为什么不用CHECKSUM()两列来存储每个关系的哈希? 它会更轻。

EDIT2:不要忘记这是一个爱情应用程序。 人们与每个人都不匹配,因为他们有性取向。

有几件事需要考虑。

首先,除非您知道需要运行的查询类型,否则表的大小并不是非常有趣。 正如其他人所说的那样,拥有数亿行的表格没有什么可担心的,如果你在可索引字段上查询,你可以扩展到数十亿行而不需要通过购买更大更好的硬件来寻求外来解决方案。 因此,90%的查询都是一个解决方案

select * from users where user_id not in (select interacted_user_id from interactions where interacting_user_id = $current_user) limit 10

我的猜测是,这将扩展到笔记本电脑上的数亿行,以及体面的服务器上的数十亿行。 我强烈建议使用一个简单的关系解决方案,无需分区或其他奇特的解决方案,直到您已经扩展到不再适用的程度,并且您已经调整了查询​​并尽可能地升级了硬件。 这比任何其他解决方案便宜/容易。

更大的挑战将是地理空间方面 - 大概是,您希望根据与当前用户的距离来订购结果。

您可以对数据进行分区的一种方法是按区域收集“交互”。 这需要一些思考 - 你可能不希望“硬”界限,而是有重叠的地理位置。 地图上的每个点可能都有一些重叠的“区域”,每个区域都有自己的表格。 您在一个区域中拥有的用户越多,重叠的圈子越小 - 曼哈顿可能有3个区域,格陵兰可能只有1.您的查询然后查看每个重叠区域的表格,并联合之前没有的用户与当前用户互动。

如果1人不喜欢该人2,则不需要向该人显示该人2.即使您出示他,他们也永远不会匹配。 因此,您的计算1K x 1K = 1M有点过高估计。

但是,如果您仍然希望为这两个用户提供喜欢/不喜欢的设置,您可能会考虑这种“压缩”行的糟糕想法。

想象一下,你有一个这样的序列:

| Person 1 | Person 2 |  Op       |
| -------- | -------- | --------- |
| 0001     | 1010     |  Dislike  |
| 0001     | 1011     |  Dislike  |
| 0001     | 1012     |  Dislike  |
| 0001     | 1013     |  Dislike  |
| 0001     | 1015     |  Like     |
| 0001     | 1017     |  Dislike  |
| 0001     | 1018     |  Dislike  |
| 0001     | 1019     |  Dislike  |
| 0001     | 1021     |  Like     |

如果你有id跟随彼此,你可能会将它们显示为

| Person 1 | Person 2 |  Op       | N    |
| -------- | -------- | --------- | ---- |
| 0001     | 1010     |  Dislike  | 3    |
| 0001     | 1015     |  Like     | 0    |
| 0001     | 1017     |  Dislike  | 2    |
| 0001     | 1021     |  Like     | 0    |

其中N是序列中的最大id(例如1010 + 3 = 1013)。 如果将N定义为无符号tinyint,则序列的最大可能大小可以为255,这意味着,理论上,255个连续的不喜欢/喜欢可以保存为1个记录。

查询将是这样的(想象你正在寻找id 1013):

SELECT a.* 
FROM (
    SELECT *
    FROM `table`
    WHERE person_1 = 0001
      AND person_2 >= (1013 - 255) -- 255 is a max size of a sequense 
      AND person_2 <= 1013
) a
WHERE a.person_2 <= 1013 AND a.person_2 + N >= 1013

子选择将限制可能记录的范围,然后主选择将匹配记录(如果存在)。 在这种情况下,它将是

| Person 1 | Person 2 |  Op       | N    |
| -------- | -------- | --------- | ---- |
| 0001     | 1010     |  Dislike  | 3    |

但是,就个人而言,我会选择这一点,因为它的简单性而更喜欢你当前的解决方案。

或者作为另一种变体,您可以通过这种方式压缩表格

| Person 1 | Person 2 | Max Person 2 |  Op       |
| -------- | -------- | ------------ | --------- |
| 0001     | 1010     | 1013         |  Dislike  |
| 0001     | 1015     | 1015         |  Like     |
| 0001     | 1017     | 1019         |  Dislike  |
| 0001     | 1021     | 1021         |  Like     |

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM