sql >> Database >  >> NoSQL >> MongoDB

Veel tot veel relaties met MongoDB op grote schaal

Dit is een goede vraag die de problemen met te veel inbedding illustreert en hoe hiermee om te gaan.

Voorbeeld:vind-ik-leuks posten

Laten we bij het voorbeeld blijven van gebruikers die berichten leuk vinden, wat een eenvoudig voorbeeld is. De andere relaties zouden dienovereenkomstig moeten worden behandeld.

Je hebt helemaal gelijk dat het opslaan van de likes in de post vroeg of laat tot het probleem zou leiden dat zeer populaire posts de maximale grootte zouden bereiken.

Dus je viel correct terug om een ​​post_likes . te maken verzameling. Waarom noem ik dit correct? Omdat het past bij uw gebruiksscenario's en functionele en niet-functionele vereisten!

  • Het schaalt oneindig (nou ja, er is een theoretische limiet, maar het is gigantisch)
  • Het is gemakkelijk te onderhouden (maak een unieke index over post_id en liked_user_id ) en gebruik (zowel de gebruiker als de post zijn bekend, dus het toevoegen van een like is een eenvoudige toevoeging of meer waarschijnlijk een upsert)
  • Je kunt er gemakkelijk achter komen welke gebruikers welke post leuk vinden en welke post door welke gebruikers wordt gewaardeerd

Ik zou de verzameling echter een beetje uitbreiden om onnodige zoekopdrachten te voorkomen voor bepaalde gebruiksgevallen die vaak voorkomen.

Laten we voorlopig aannemen dat titels en gebruikersnamen van berichten niet kunnen worden gewijzigd. In dat geval zou het volgende datamodel zinvoller kunnen zijn

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

Laten we nu aannemen dat je de gebruikersnaam wilt weergeven van alle gebruikers die een bericht leuk vonden. Met het bovenstaande model zou dat een enkele, vrij snelle vraag zijn:

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

Met alleen de ID's die zijn opgeslagen, zou deze nogal gebruikelijke taak ten minste twee zoekopdrachten nodig hebben en - gezien de beperking dat er een oneindig aantal likers voor een bericht kan zijn - mogelijk enorm geheugenverbruik (u moet de gebruikers-ID's in het RAM-geheugen opslaan).

Toegegeven, dit leidt tot enige redundantie, maar zelfs als miljoenen mensen een bericht leuk vinden, hebben we het slechts over een paar megabytes aan relatief goedkope (en eenvoudig te schalen) schijfruimte terwijl het veel prestatie oplevert. in termen van gebruikerservaring.

Nu komt het punt:zelfs als de gebruikersnamen en posttitels aan verandering onderhevig zijn, hoefde je alleen maar een multi-update uit te voeren:

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

U handelt erop in dat het een tijdje duurt om vrij zeldzame dingen te doen, zoals het wijzigen van een gebruikersnaam of een bericht voor extreme snelheid voor gebruikssituaties die extreem vaak voorkomen.

Kortom

Houd er rekening mee dat MongoDB een documentgeoriënteerde database is. Documenteer dus de gebeurtenissen waarin u geïnteresseerd bent met de waarden die u nodig heeft voor toekomstige zoekopdrachten en modelleer uw gegevens dienovereenkomstig.



  1. How-to:Gescande PDF's indexeren op schaal met minder dan 50 regels code

  2. waarom DuplicateKeyError:E11000 dubbele sleutel fout index:test.test.$notification_1 dup sleutel:{:null}

  3. Mongo DB:Query voor documenten die momenteel live zijn op basis van start- en einddatum

  4. MongoCursorTimeoutUitzondering voor aggregatiefunctie