español mysql performance twitter group-by twitter-follow

español - mysql follow y retweet-like funcionalidad



mysql español (2)

Esta es una pregunta un poco desafiante pero divertida. Considera tener estas tablas

tweets

tweet_id | retweet_of_id | user_id

seguir

user_id | followed_user_id

Así que almacenamos cada "retweet como un tweet separado " apuntando a la identificación del tweet original ( retweet_of_id ). Esto es porque quiero tener comentarios debajo de cada uno por separado. Si algo no es un retweet, retweet_of_id será 0 .

¿Cómo recupero lo siguiente utilizando MySQL de manera eficiente ?

  • Mis propios tweets
  • Todos los tweets originales (de los usuarios que sigo)
  • Y el primer retweet (por un usuario que sigo) de un tweet (de un usuario que no sigo)

Y que el resultado debería ser una combinación de ambos (en orden) al igual que lo hace Twitter.
Tenga en cuenta que puede haber 1,000,000 de tweets y solo necesitamos los más recientes (p. Ej .: 10).

Aquí hay un ejemplo (soy el usuario 1 y sigo al usuario 2 y 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)

Entonces, el orden final deberían ser estos tweets: 7, 4, 3, 2 (comenzando con el más reciente)


todos los tweets originales (de los usuarios que sigo)

1 usuarios que sigo:

select user_id from follow where followed_user_id= MyOwnID

2 todos los tweets originales:

select * from tweets where retweed_of_id=0

ambos combinados:

select * from tweets where retweed_of_id=0 and user_id in (select user_id from follow where followed_user_id= MyOwnID)

eso debería ser, ¿o extrañé algo?


Así es como lo resolví
(ambos asumen que los tweets están ordenados por su tweet_id ASC)

Solución 1 (correcto, funciona rápido)

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

Solución 2 (da los resultados correctos, pero es lenta para 1,000,000 de tweets)

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