Come strutturare un database DynamoDB per consentire query per i post di tendenza?
-
27-10-2019 - |
Domanda
Ho intenzione di utilizzare la seguente formula per calcolare i post di "tendenza":
Trending Score = (p - 1) / (t + 2)^1.5
P = voti (punti) dagli utenti. T = tempo dalla presentazione in ore.
Sto cercando consigli su come strutturare le mie tabelle di database in modo da poter interrogare per i post di tendenza con DynamoDB (un servizio di database NoSQL da Amazon).
DynamoDB richiede una chiave primaria per ogni elemento in una tabella. La chiave primaria può consistere in 2 parti: l'attributo hash (stringa o numero) e l'attributo dell'intervallo (stringa o numero). L'attributo hash deve essere unico per ogni articolo ed è richiesto. L'attributo di intervallo è facoltativo, ma se usato DynamoDB costruirà un indice di intervallo ordinato sull'attributo di intervallo.
La struttura che avevo in mente va come segue:
TableName: utenti
HashAttribute: user_id
RangeAttribute: NONE
OtherFields: first_name, last_name
TableName: post
HashAttribute: post_id
RangeAttribute: NONE
OtherFields: user_id,title, content, points, categories[ ]
TableName: categorie
HashAttribute: category_name
RangeAttribute: post_id
OtherFields: title, content, points
TableName: contatori
HashAttribute: counter_name
RangeAttribute: NONE
OtherFields: counter_value
Quindi ecco un esempio dei tipi di richieste che farei con la seguente tabella Imposta (esempio: user_id = 100):
Azione dell'utente 1:
L'utente crea un nuovo post e tagga il post per 2 categorie (baseball, calcio)
Query (1):
Controlla il valore corrente per Counter_name = 'post_id' e incremento+1 e usa il nuovo post_id
Query (2): Inserire quanto segue nella tabella dei post:
post_id=value_from_query_1, user_id=100, title=user_generated, content=user_generated, points=0, categories=['baseball','soccer']
Query (3):
Inserire quanto segue nella tabella delle categorie:
category_name='baseball', post_id=value_from_query_1, title=user_generated, content=user_generated, points=0
Query (4):
Inserire quanto segue nella tabella delle categorie:
category_name='soccer', post_id=value_from_query_1, title=user_generated, content=user_generated, points=0
L'obiettivo finale è essere in grado di condurre i seguenti tipi di domande:
1. Interrogazione per i post di tendenza
2. Interrogazione per i post in una determinata categoria
3. Interrogazione per i post con i valori più alti
Qualcuno ha idea di come potrei strutturare i miei tavoli in modo da poter fare una domanda per i post di tendenza? O è qualcosa che do la possibilità di fare passando a DynamoDB?
Soluzione
Sto iniziando con una nota sul tuo commento con il timestamp vs post_id.
Dal momento che userai DynamoDB come generatore post_id, c'è un problema di scalabilità proprio lì. Quei numeri sono intrinsecamente insignificanti e è meglio usare un oggetto Data. Se hai bisogno di creare post in un tempo di velocità folle, puoi iniziare a leggere su come lo sta facendo Twitterhttp://blog.twitter.com/2010/Announcing-Snowflake
Ora torniamo al tuo controllo di tendenza:
Credo che il tuo scenario stia abusando di DynamoDB.
Supponiamo che tu abbia una categoria calda che contiene la maggior parte dei post. Fondamentalmente dovrai scansionare tutti i post (poiché i dati non sono distribuiti bene) e per ogni inizio a guardare i punti e fare i confronti nel tuo server. Questo non funzionerà o sarà molto costoso poiché ogni volta che probabilmente utilizzerai tutta la capacità delle unità di lettura riservata.
L'approccio DynamoDB per questo tipo di tendenza che controlla è l'utilizzo di MapReduce
Leggi qui come implementarli: http://aws.typepad.com/aws/2012/01/aws-howto-using-mazon-elastic-mapreduce-with-dynamodb.html
Non riesco a specificare un tempo, ma credo che troverai questo approccio scalabile, anche se non sarai in grado di usarlo spesso.
In un'altra nota: potresti conservare un elenco delle domande alla moda "Top 10/100" e le aggiornate in "in tempo reale" quando un post viene votato: ottieni l'elenco, controlla se è necessario essere aggiornato con il nuovo Domanda evocata e salvarlo al DB, se necessario.