Ответ 1
Наоборот, решение 1 и 2 - ваш лучший выбор. Решение 3 можно учитывать, когда частота обновления/создания очень меньше по сравнению с частотой чтения проектов и пользователей, так как даже при обновлении/создании требуется два запроса, легкость чтения будет компенсировать это.
Чтобы выбрать среди решений 1 и 2, вам необходимо учитывать частоты чтения. Будете ли вы нуждаться в проектах пользователя или использовать проект более часто и выбирать в соответствии с этим. Если вы считаете, что они имеют одинаковую частоту, лучше сохранить объект пользователя как можно менее сгруппированным. Какой бы вариант вы ни выбрали, подумайте о сохранении index
в массиве, хранящем _id
(проектов или пользователей).
Например,
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, но всегда существует опасность несогласованности данных, о которой вам нужно позаботиться.
Индексирование только ускоряет работу. Пройдите документы и сделайте немного поиска в Google. Ничего особенного. Запрос по индексированным массивам эффективен, чем обычные массивы. Напр. Предположим, вы используете решение 2. Сохраните идентификаторы проекта в поле project_ids.
Вы можете легко получить проекты пользователя. Это прямо.
Но получить пользователей проекта1. Вам нужен такой запрос.
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.
Similary для решения 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 лучше, я думаю. Могут быть случаи, когда вам нужен пользователь без его проектов, но шансы на выполнение проекта без пользователей довольно низки. Но это зависит от вашего конкретного случая использования.