Abbiamo un sistema di classificazione nel nostro sito Web che consente agli utenti di fornire feedback a 3 diverse domande su un utente.
Attualmente calcoliamo la valutazione utilizzando le medie utilizzando la seguente query sul nostro RDBMS:
SELECT AVG(question_1), AVG(question_2), AVG(question_3)
FROM ratings
WHERE user_id = 1
Questa query non è scalabile anche quando il risultato è memorizzato nella cache (e lo è) poiché alcuni dei nostri utenti hanno milioni di voti.
L'uso di un indice funzionale non è un'opzione perché il nostro RDBMS non li supporta e l'utilizzo di uno rallenterebbe significativamente le scritture.
La soluzione che ho trovato è quella di creare un log di sola append delle medie in un dato intervallo di tempo e unirle periodicamente usando una media ponderata.
Quindi avremmo finito con la seguente struttura dati per utente:
| question1_avg | question2_avg | question3_avg | ratings_count | timestamp | | 3.4 | 4.5 | 4.9 | 10000 | 1480429792 | | 5 | 5 | 5 | 30 | 1480429848 |
Quindi il processo di unione sarà simile a:
(3.4 * 10000 + 5 * 30) / 10030
I record precedenti verranno rimossi e la nuova media verrà aggiunta al registro.
Questo disegno è corretto? Funzionerà su larga scala?
Dove conserverai quel tipo di dati? Un archivio di documenti (come MongoDB), un archivio di valori-chiave (come Redis) o un RDBMS?
Poiché questo concetto è molto simile ai contatori CRDT, ho cercato di trovare un tipo di dati replicati convergenti che ti consente per calcolare le medie ma non sono riuscito a trovarne una. C'è una struttura dati che mi è sfuggita?
C'è un altro algoritmo o tipo di dati che dovrei esaminare?