Integendeel, oplossing 1 en 2 zijn de beste keuze. Oplossing 3 kan worden overwogen wanneer de update-/aanmaakfrequentie erg laag is in vergelijking met de leesfrequentie van projecten en gebruikers, ook al vereist het bijwerken/maken twee vragen, het leesgemak zal dat compenseren.
Om uit oplossing 1 en 2 te kiezen, moet u rekening houden met de leesfrequenties. Heb je vaker projecten van een gebruiker of gebruik van een project nodig en kies je op basis daarvan. Als u denkt dat beide relatief dezelfde frequentie hebben, is het beter om het gebruikersobject zo min mogelijk geclusterd te houden. Welke optie je ook kiest, overweeg om een index
. bij te houden op de array die de _id
. opslaat s (van projecten of gebruikers).
Bijvoorbeeld.
userSchema = new Schema(
{//otherstuff
project_ids: [{type: Schema.Types.ObjectId, ref: 'Project'}})
...
})
userSchema.index({'project_ids':1})
of
projectSchema = new Schema(
{//otherstuff
user_ids: [{type: Schema.Types.ObjectId, ref: 'User'}})
...
})
projectSchema.index({'user_ids':1})
Een index bijhouden op de array van _id
zal de snelheid van uw zoekopdrachten enorm verbeteren aan de kant waar u vreest dat er aanzienlijke overhead zal zijn.
Maar bewaar de index
alleen als deze relatie een belangrijke relatie is met veel queries. Als dit slechts een nevenfunctie van uw project is, kunt u without
. doen ook een index.
Als de gebruiker veel dingen kan doen en veel relaties heeft, heb je dat gebruikersobject constant nodig in je app, dus als je app niet projectspecifiek is, is het beter om de project-ID's niet in het gebruikersschema te plaatsen . Maar aangezien we alleen de ID's plaatsen, is het sowieso niet veel van een overhead. Daar hoef je je geen zorgen over te maken.
Reg index op beide arrays:Ja dat kan natuurlijk. Maar als je voor oplossing 3 gaat, heb je helemaal geen index nodig, omdat je geen query hoeft uit te voeren om de lijst met projecten van een gebruiker of de lijst met gebruikers in een project te krijgen. Oplossing 3 maakt lezen heel gemakkelijk, maar schrijven een beetje omslachtig. Maar zoals je al zei, je use case is reading>>writing
, ga voor oplossing 3, maar er is altijd een gevaar van inconsistentie van gegevens waar u voor moet zorgen.
Indexeren maakt dingen alleen maar sneller. Blader door de documenten en ga een beetje googlen. Niets speciaals. Query's uitvoeren op geïndexeerde arrays is efficiënter dan normale arrays. Voor bijv. Laten we aannemen dat u oplossing 2 gebruikt. Bewaar de project-ID's in het veld project_ids.
U kunt de projecten van een gebruiker gemakkelijk krijgen. Dit is rechttoe rechtaan.
Maar om gebruikers van project1. Je hebt een zoekopdracht als deze nodig.
User.find({project_ids:project._id},function(err,docs){
//here docs will be the list of the users of project1
})
//The above query might be slow if the user base is large.
//But it can be improved vastly by indexing the project_ids field in the User schema.
Gelijkaardig voor oplossing 1. Elk project heeft het veld user_ids. Laten we aannemen dat we een gebruiker1 hebben. Om de projecten van de gebruiker te krijgen, doen we de volgende vraag
Project.find({user_ids:user1._id},function(err,docs){
//here docs will be the projects of user1
//But it can be improved vastly by indexing the user_ids field in the Project schema.
Als je nadenkt over oplossing 1 versus oplossing 2, is oplossing 1 beter denk ik. Er kunnen gevallen zijn waarin u een gebruiker zonder zijn projecten nodig heeft, maar de kans dat u het project zonder gebruikers nodig heeft, is vrij klein. Maar het hangt af van uw exacte gebruiksscenario.