2009-11-29 7 views
14

Recentemente sto esplorando database NoSQL. Ho bisogno di un consiglio su come conservare i dati nel modo più ottimale ed efficiente per un determinato problema. Sto prendendo di mira MongoDB, ora. Tuttavia dovrebbe essere lo stesso con CouchDB.Ho bisogno di un consiglio su NoSQL/MongoDb e struttura dati/modelli

Diciamo che abbiamo questi 3 modelli:

Story: 
id 
title 

User: 
id 
name 

Vote: 
    id 
    story_id 
    user_id 

io voglio essere in grado di chiedere al database di queste domande:

  • Chi ha votato questa storia?
  • Che cosa ha votato questo utente?

Sto facendo semplici join mentre lavoro con un DB relazionale. La domanda è: come devo archiviare i dati per tali oggetti per essere più efficienti.

Ad esempio, se si memorizzano gli oggetti Voto come sottoraccolta di Storie, non sarà facile ottenere le informazioni - "Che utente ha votato per".

risposta

7

Suggerirei di memorizzare voti come elenco di storie _id s in ciascun utente. In questo modo puoi scoprire quali storie un utente ha votato semplicemente guardando la lista. Per ottenere gli utenti che hanno votato per una storia che si può fare qualcosa di simile:

db.users.find({stories: story_id})

dove story_id è la _id della storia in questione. Se si crea un indice nel campo stories, entrambe le query saranno veloci.

+0

Beh, in effetti voglio memorizzare più informazioni in un modello di voto. Ad esempio: created_at, ip, user_agent. Devo memorizzare i dati nell'elenco di storie della collezione di utenti? –

+0

Puoi memorizzare i voti come una serie di sotto-documenti, ognuno come '{story_id: ..., created_at: ..., ip: ...}', ecc. Quindi la query diventa 'find ({'stories .story_id ': ...}) '. Puoi indicizzare anche quello. – mdirolf

+0

Beh, ho un database abbastanza grande con alcuni record M e proverò lo scenario sopra. –

2

Ok, hai fornito un modello di dati normalizzato come faresti in una configurazione SQL.

A mio parere non lo fai in MongoDB. È possibile memorizzare riferimenti, ma non per motivi di prestazioni nel caso generale.

Non sono un esperto nell'area NoSQL in alcun modo, ma perché non segui semplicemente le tue esigenze e memorizzi gli utenti (id) che hanno votato per una storia nella raccolta di storie e nella storia (ids) un utente ha votato nella raccolta degli utenti?

1

In CouchDB questo è molto semplice. Un punto di vista emette:

function(doc) { 
if(doc.type == "vote") { 
    emit(doc.story_id, doc.user_id); 
} 
} 

Un'altra vista emette:

function(doc) { 
if(doc.type == "vote") { 
    emit(doc.user_id, doc.story_id); 
} 
} 

Entrambi sono domande estremamente veloce dal momento che non v'è alcun join. Se hai bisogno di dati utente o di storie, CouchDB supporta il recupero di documenti multipli. Anche abbastanza veloce ed è un modo per fare un "join".

+0

Avrò bisogno di domande in questo scenario, vero? Uno per interrogare un indice per i documenti Voti e uno per ottenere i documenti per Utente/Storia. –

+0

@Stanislav. È corretto. Prima devi recuperare i voti e poi recuperare utenti e/o storie per quei voti. – dnolen

3
  • non preoccupatevi se le vostre domande sono efficienti fino a quando non inizia alla materia
  • secondo al di sotto di citazione, si sta facendo male

Il modo in cui mi sono state andando circa la mind switch è dimenticare tutto il database alltogether.Nel mondo db relazionale devi sempre preoccuparti della normalizzazione dei dati e la struttura della tabella. Lascia perdere tutto. Basta impaginare la tua pagina web. Posali tutti fuori. Adesso guardali. Il tuo già 2/3 lì. Se dimentichi la nozione che le dimensioni del database contano e i dati non devono essere duplicati rispetto al tuo 3/4 lì e non hai nemmeno dovuto scrivere alcun codice allo ! Lascia che le tue opinioni dettino i tuoi modelli. Non è necessario prendere gli oggetti e renderli più 2 dimensionale come nel mondo relazionale . È possibile memorizzare oggetti con forma ora.

how-to-think-in-data-stores-instead-of-databases

0

Ho cercato in MongoDB e CouchDB molto ultimamente, ma la mia intuizione è limitato. Tuttavia, quando si pensa di archiviare i voti all'interno del documento della storia, potrebbe essere necessario preoccuparsi di raggiungere il limite di dimensione del documento di 4 MB. Anche se non lo fai, potresti aumentare costantemente la dimensione del documento per far sì che venga spostato e rallentando così le tue scritture (vedi come i documenti sono dimensionati in MongoDB).

Per quanto riguarda CouchDB, questo tipo di cose sono abbastanza semplici, eleganti e abbastanza veloci una volta calcolati gli indici di visualizzazione. Personalmente, tuttavia, ho esitato a fare un progetto simile in CouchDB a causa di benchmark che lo mostrano progressivamente rallentando in misura considerevole man mano che il database cresce (e gli indici di visualizzazione crescono). Mi piacerebbe vedere alcuni benchmark più recenti che mostrano le prestazioni di CouchDB all'aumentare delle dimensioni del database. Voglio provare MongoDB o CouchDB, ma SQL sembra ancora così efficiente e logico, quindi rimarrò fino a quando il progetto non si adatta alla tentazione.

Problemi correlati