Naopak, řešení 1 a 2 jsou vaše nejlepší sázka. Řešení 3 lze zvážit, když je frekvence aktualizací/vytváření velmi nižší ve srovnání s frekvencí čtení projektů a uživatelů, protože i když aktualizace/vytváření vyžaduje dva dotazy, snadnost čtení to vynahradí.
Chcete-li si vybrat mezi řešením 1 a 2, musíte vzít v úvahu čtecí frekvence. Budete potřebovat projekty uživatele nebo použití projektu častěji a podle toho vybírat. Pokud máte pocit, že oba mají relativně stejnou frekvenci, je lepší ponechat uživatelský objekt co nejméně shlukovaný. Ať už zvolíte jakoukoli možnost, zvažte ponechat index
na poli uchovávajícím _id
s (projektů nebo uživatelů).
Například.
userSchema = new Schema(
{//otherstuff
project_ids: [{type: Schema.Types.ObjectId, ref: 'Project'}})
...
})
userSchema.index({'project_ids':1})
nebo
projectSchema = new Schema(
{//otherstuff
user_ids: [{type: Schema.Types.ObjectId, ref: 'User'}})
...
})
projectSchema.index({'user_ids':1})
Uchovávání indexu na poli _id
výrazně zvýší rychlost vašich dotazů na straně, kde se obáváte, že bude značná režie.
Ale ponechte index
pouze v případě, že je tento vztah důležitým vztahem s mnoha probíhajícími dotazy. Pokud je to jen vedlejší funkce vašeho projektu, můžete se obejít without
také index.
Pokud uživatel může dělat spoustu věcí a má spoustu vztahů, budete tento uživatelský objekt potřebovat neustále v celé své aplikaci, takže pokud vaše aplikace není specifická pro projekt, bylo by lepší nevkládat ID projektu do uživatelského schématu. . Ale protože právě vkládáme ID, stejně to není příliš velká režie. Není třeba si s tím dělat starosti.
Reg index na obou polích:Ano, samozřejmě můžete. Ale když se rozhodnete pro řešení 3, nepotřebujete index vůbec, protože nebudete provádět dotaz, abyste získali seznam projektů uživatele nebo seznam uživatelů v projektu. Řešení 3 velmi usnadňuje čtení, ale psaní je trochu těžkopádné. Ale jak jste zmínil, váš případ použití zahrnuje reading>>writing
, použijte řešení 3, ale vždy existuje nebezpečí nekonzistence dat, o kterou se musíte postarat.
Indexování jen urychluje věci. Projděte si dokumenty a trochu googlujte. Nic přepychového. Dotazování přes indexovaná pole je efektivnější než normální pole. Např. Předpokládejme, že používáte řešení 2. Uložte ID projektu do pole project_ids.
Můžete snadno získat projekty uživatele. Toto je přímočaré.
Ale získat uživatele project1. Potřebujete takový dotaz.
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.
Podobně pro řešení 1. Každý projekt má pole user_ids. Předpokládejme, že máme user1. Chcete-li získat projekty uživatele, provedeme následující dotaz
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.
Pokud přemýšlíte nad řešením 1 vs řešením 2, myslím, že řešení 1 je lepší. Mohou nastat případy, kdy potřebujete uživatele bez jeho projektů, ale šance na vyžadování projektu bez uživatelů je velmi nízká. Ale záleží na vašem přesném případu použití.