mysql跟随和转推类似的功能

tra*_*ter 5 mysql twitter performance group-by twitter-follow

这是一个有点挑战但有趣的问题.考虑拥有这些表格

微博

tweet_id | retweet_of_id | user_id
Run Code Online (Sandbox Code Playgroud)

跟随

user_id | followed_user_id
Run Code Online (Sandbox Code Playgroud)

因此,我们将每个"转发作为单独的推文"存储在指向原始推文的id(retweet_of_id)中.这是因为我想分别在每一个下面发表评论.如果某件事不是转发,那么retweet_of_id将是0.

如何有效地使用MySQL检索以下内容?

  • 我自己的推文
  • 所有原始推文(来自我关注的用户)
  • 并且第一次转推(由我关注的用户)推文(来自我不遵循的用户)

并且结果应该是两者的组合(按顺序),就像twitter一样.
请考虑可能有1,000,000条推文,我们只需要最新的推文(例如:10).


这是一个例子(我是用户1,我关注用户2和3)

tweet_id | retweet_of_id | user_id
----------------------------------
    1            0            4          <- EXCLUDE (I don't follow user 4)
    2            0            2          <- INCLUDE (I follow user 2)
    3            0            3          <- INCLUDE (I follow user 3)
    4            1            2          <- INCLUDE (I follow user 2 & first RT)
    5            1            3          <- EXCLUDE (I already have the first RT)
    6            2            3          <- EXCLUDE (I already have the orignal)
    7            0            1          <- INCLUDE (My own tweet)
Run Code Online (Sandbox Code Playgroud)

所以最后的订单应该是这些推文:( 7, 4, 3, 2 从最近开始)

tra*_*ter 1

这是我解决这个问题的方法
(两者都假设推文按其tweet_idASC 排序)

解决方案1(正确,运行速度快)

SELECT tweet_id,
FROM tweets 
WHERE user = 1 OR user IN (2,3)  
GROUP BY  IF(retweet_of_id = 0, tweet_id, retweet_of_id)
ORDER BY tweet_id DESC
Run Code Online (Sandbox Code Playgroud)

解决方案 2(给出了正确的结果,但对于 1,000,000 条推文来说速度太慢了)

SELECT p1.tweet_id FROM tweets p1 
LEFT JOIN tweets p2 
       ON p2.user IN (2,3)
      AND p1.tweet_id > p2.tweet_id
      AND (p1.retweet_of_id = p2.tweet_id 
           OR p1.retweet_of_id AND p1.retweet_of_id = p2.retweet_of_id )
WHERE p2.tweet_id IS NULL
  AND (p1.user = 1 OR p1.user IN (2,3)) 
ORDER BY p1.tweet_id DESC
Run Code Online (Sandbox Code Playgroud)