MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Molte a molte relazioni con MongoDB su larga scala

Questa è una buona domanda che illustra i problemi con l'overemebedding e come affrontarlo.

Esempio:pubblica Mi piace

Continuiamo con l'esempio degli utenti che apprezzano i post, che è un semplice esempio. Le altre relazioni dovrebbero essere gestite di conseguenza.

Hai assolutamente ragione sul fatto che archiviare i Mi piace all'interno del post prima o poi porterebbe al problema che i post molto popolari raggiungerebbero il limite di dimensioni.

Quindi sei tornato correttamente per creare un post_likes collezione. Perché lo chiamo corretto? Dal momento che si adatta ai tuoi casi d'uso e ai tuoi requisiti funzionali e non!

  • Ridimensiona indefinitamente (beh, c'è un limite teorico, ma è enorme)
  • È facile da mantenere (crea un indice univoco su post_id e liked_user_id ) e utilizzare (sia l'utente che il post sono noti, quindi aggiungere un like è un semplice inserto o più probabilmente un upsert)
  • Puoi scoprire facilmente a quali utenti piace quale post e quale post è piaciuto a quali utenti

Tuttavia, espanderei un po' la raccolta per evitare query non necessarie per alcuni casi d'uso frequenti.

Supponiamo per ora che i titoli dei post e i nomi utente non possano essere modificati. In tal caso, il seguente modello di dati potrebbe avere più senso

{
  _id: new ObjectId(),
  "post_id": someValue,
  "post_title": "Cool thing",
  "liked_user_id": someUserId,
  "user_name": "JoeCool"
}

Ora supponiamo che tu voglia visualizzare il nome utente di tutti gli utenti a cui è piaciuto un post. Con il modello sopra, sarebbe una query singola, piuttosto veloce:

db.post_likes.find(
  {"postId":someValue},
  {_id:0,user_name:1}
)

Con solo gli ID memorizzati, questo compito piuttosto usuale richiederebbe almeno due query e, dato il vincolo che può esserci un numero infinito di Mi piace per un post, potenzialmente enorme consumo di memoria (dovresti memorizzare gli ID utente nella RAM).

Certo, questo porta a una certa ridondanza, ma anche quando a milioni di persone piace un post, stiamo parlando solo di pochi megabyte di spazio su disco relativamente economico (e facile da scalare) guadagnando al contempo molte prestazioni in termini di esperienza utente.

Ora arriva il punto:anche se i nomi utente e i titoli dei post sono soggetti a modifiche, devi solo eseguire un aggiornamento multiplo:

db.post_likes.update(
  {"post_id":someId},
  { $set:{ "post_title":newTitle} },
  { multi: true}
)

Stai scambiando che ci vuole un po' di tempo per fare cose piuttosto rare come cambiare un nome utente o un post per una velocità estrema per casi d'uso che si verificano estremamente spesso.

Linea inferiore

Tieni presente che MongoDB è un database orientato ai documenti. Quindi documenta gli eventi che ti interessano con i valori di cui hai bisogno per le query future e modella i tuoi dati di conseguenza.