Certo, il modo migliore, probabilmente, sarebbe quello di utilizzare un NoSQL database, o Redis, ma in fase di startup comporta diversi costi e quindi, proviamo a usare MySQL!
Il succo della questione è questo:
Realizzare un Acitivity Feed (come FB, Twitter insomma) in MySQL senza ammazzare le risorse con query che utilizzino SELETE ... FROM activity_feed WHERE uid IN (mille id di persone che seguo)
Leggendo qua e la si capisce chiaramente che esistono due tipi di gestione per la creazione di un sistema del genere e sono Pull e Push. Vale a dire inserire questi dati un un sistema indicizzato dove ogni utente ha una PROPRIA lista di attività da visualizzare a seconda degli utenti che segue.
Con il metodo Pull, questa lista, viene generata nel momento in cui si cerca di visualizzare il news feed, ed è credo sconsigliabile. Perché comporterebbe la fatica di trovare le attività che l'utente deve visualizzare ATTRAVERSO alcune interrogazioni. Tipo vedere l'ultima attività importata nella lista e scorrere la tabella activity_feed cercando nuove attività delle persone che segue.
Il metodo Push invece, concede la possibilità di inserire una nuova attività fatta da un qualsiasi utente nella lista delle attività da visualizzare delle persone che lo seguono. Quindi avviene nel momento in cui l'attività viene creata. Questo permette all'utente che segue di richiedere la pagina Activity Feed e visualizzare, senza nessun processo oltre alla query di interrogazione dei dati, le notizie. Ovviamente, il problema di questo metodo è che nel momento in cui si crea un attività, si devono aggiornare le liste di tutti i follower (che potrebbero anche essere 100.000, ipotizziamo).
Oltre a chiedervi quale dei due metodi ritenete migliori, volevo anche ipotizzare una struttura possibile de DB.
Premesso che l'attività da visualizzare deve essere registrata in un campo TEXT come JSON, perché comporta diverse interrogazioni (e non è un problema, perché non si deve eseguire nessuna ricerca su questi dati), ecco cosa ho pensato.
ACTIVITY_FEED <- fixed/length
-----------------
AID - INT, PRIMARY KEY, A_I <- identificativo univoco delle attività
UID - INT <- identificativo dell'utente che ha svolto l'attività
TYPE - ENUM(post,commento,like,etc) <- Tipo di attività svolta
RID - INT <- id realtivo all'attività svolta (tipo l'id del post scritto dall'utente o del commento)
TIMESTAMP - DATETIME <- il timestamp dell'attività
ACTIVITY_FEED_INDEX <- fixed/length
------------------
UID - INT <- ID dell'utente che deve visualizzare l'attività
AID - INT <- ID dell'attività che l'utente deve visualizzre
TIMESTAMP <- Il Timestamp dell'attività
PRIMARY KEY (uid,aid)
ACTIVITY_FEED_CACHE
------------------
AID - INT <- ID dell'attività in cache
CACHE_DATA - TEXT <- Contiene il JSON dell'attività con tutti i dettagli
Ora Activity_feed è identificativo per un eventuale rielaborazione della chace, nel caso l'attività venga modificata o altro.
L'idea è quella di inserire in ACTIVITY_FEED_INDEX le righe relative a tutti gli utenti che seguono l'utente che ha realizzato l'attività. Così, che in fase di richiesta della pagina, l'utente con una query del tipo:
SELECT cache.cache FROM activity_feed_index as index INNER JOIN activity_feed_cache AS cache ON cache.aid = index.aid WHERE index.uid = 'USER_ID'
potrà ottenere i risultati.
Vi sembra efficiente? E se no come impostereste questo tipo di interrogazione?