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