Напротив, решение 1 и 2 са най-добрият ви залог. Решение 3 може да се разглежда, когато честотата на актуализиране/създаване е много по-малка в сравнение с честотата на четене на проекти и потребители, тъй като въпреки че за актуализиране/създаване са необходими две заявки, лекотата на четене ще компенсира това.
За да изберете между решение 1 и 2, трябва да вземете предвид честотите на четене. Ще имате ли нужда от проекти на потребител или употреби на проект по-често и избирайте според това. Ако смятате, че и двете са с относително една и съща честота, по-добре е потребителският обект да бъде възможно най-малко групиран. Каквато и опция да изберете, помислете за запазването на index
в масива, съхраняващ _id
s (на проекти или потребители).
Например.
userSchema = new Schema(
{//otherstuff
project_ids: [{type: Schema.Types.ObjectId, ref: 'Project'}})
...
})
userSchema.index({'project_ids':1})
или
projectSchema = new Schema(
{//otherstuff
user_ids: [{type: Schema.Types.ObjectId, ref: 'User'}})
...
})
projectSchema.index({'user_ids':1})
Поддържане на индекс в масива на _id
ще подобри значително скоростта на заявките ви от страната, където се страхувате, че ще има значителни разходи.
Но запазете index
само ако тази връзка е важна връзка с много заявки. Ако това е само странична характеристика на вашия проект, можете да правите without
индекс също.
Ако потребителят може да прави много неща и има много връзки, ще имате нужда от този потребителски обект постоянно в приложението си, така че ако приложението ви не е специфично за проекта, би било по-добре да не поставяте идентификаторите на проекта в потребителската схема . Но тъй като ние просто поставяме идентификаторите, така или иначе не е много режийни разходи. Няма нужда да се тревожите за това.
Reg индекс и на двата масива:Да, разбира се. Но когато изберете решение 3, изобщо нямате нужда от индекс, тъй като няма да правите заявка, за да получите списъка с проекти на потребител или списъка с потребители в проект. Решение 3 прави четенето много лесно, но писането е малко тромаво. Но както споменахте, че вашият случай на използване включва reading>>writing
, преминете към решение 3, но винаги има опасност от несъответствие на данните, за което трябва да се погрижите.
Индексирането просто прави нещата по-бързи. Разгледайте документите и поразгледайте малко. Нищо фантастично. Запитването върху индексирани масиви е ефективно от нормалните масиви. Напр. Да предположим, че използвате решение 2. Съхранете идентификаторите на проекта в полето project_ids.
Можете лесно да получите проектите на потребител. Това е направо.
Но за да получите потребители на project1. Трябва да направите заявка като тази.
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.
Подобно за решение 1. Всеки проект има поле user_ids. Нека приемем, че имаме user1. За да получим проектите на потребителя, правим следната заявка
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.
Ако обмисляте решение 1 срещу решение 2, предполагам, че решение 1 е по-добро. Може да има случаи, в които имате нужда от потребител без неговите проекти, но шансовете да изискате проекта без потребители са доста ниски. Но зависи от конкретния ви случай на употреба.