与 nosql 的多对多关系(mongodb 和 mongoose) [英] many to many relationship with nosql (mongodb and mongoose)

查看:28
本文介绍了与 nosql 的多对多关系(mongodb 和 mongoose)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用 mongoDb 和 mongoose.js 做多对多的关系,我知道有很多选择,我的情况是这样的:

I'm doing a relationship with many to many with mongoDb and mongoose.js, i know that there is many options, my situation is this:

我有两个文档,用户和项目,一个用户可以有多个项目,一个项目可以有多个用户,所以就我而言,我有 4 个选项:

I've two documents, user and projects, one user can have many projects and one project can have many user, so in my case i've 4 options:

1 - 项目文档中的 id_user 数组.

1 - An array of id_user inside project document.

2 - 用户文档中的 id_project 数组.

2 - An array of id_project inside user document.

3 - 项目文档中的 id_user 数组 &&一个数组用户文档中的 id_project.

3 - An array of id_user inside project document && An array of id_project inside user document.

4 - 映射用户和项目关系的第三个表(如关系数据库).

4 - A third table mapping user and project relationship(like a relational database).

选项 1 和选项 2 不可用,因为,想象在选项 1 的场景中,如果我想查找用户的所有项目,我将不得不在用户的每个项目文档数组中查找此用户 ID(在每个项目中遍历这个数组),这绝对不是一个好方法.

The option 1 and 2 are unavailable, because, imagine in the scenario of the option 1 if i wanted to find all projects from the user, i will have to look for this user id inside every project document array of the users(traverse this array in every project), this definitely isn't a good approach.

选项 3 不错,但我必须进行某种事务以确保两个文档都被写入,这还不错,因为两个文档的读取量都比写入的要多得多

The option 3 is good but i will have to make some kind of transaction to ensure that both documents will be written, it's not that bad, because both documents will be much more read than written

选项 4 更简单,因为当我向项目添加一个用户时,只需添加一个带有两个 ID 的新文档(我认为这是一个很好的解决方案,因为我不需要关心事务,这是一个很好的解决方案)解决方案?)

The option 4 is simpler because when i add one user to a project, it's just to add a new document with both id's(it's good solution i think, because i will don't need to care about transaction, it's a good solution?)

那么,最好的解决方案是什么?

So, what's the best solution?

推荐答案

相反,解决方案 1 和 2 是您最好的选择.当更新/创建频率与项目和用户的读取频率相比非常低时可以考虑解决方案3,因为即使更新/创建需要两次查询,阅读的便利性将弥补这一点.

To the contrary, solution 1 and 2 are your best bet. Solution 3 can be considered when the update/creation frequency is very less compared to read frequency of projects and users as even though to update/create, it requires two queries, the ease of reading will be make up for that.

要在解决方案 1 和 2 中进行选择,您需要考虑读取频率.您是否需要更频繁地使用某个用户的项目或项目的用途并据此进行选择.如果您觉得两者的频率相对相同,则最好使用户对象尽可能少聚集.无论您选择什么选项,请考虑在存储 _ids(项目或用户)的数组上保留一个 index.

To choose among solution 1 and 2, you need to consider the read frequencies. Will you need projects of a user or uses of a project more frequently and choose according to that. If you feel both are of relatively the same frequency, it is better to keep the user object as less clustered as possible. Whatever option you choose, consider keeping an index on the array storing the _ids (of projects or users).

例如

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 数组上保留索引将极大地提高您的查询速度,因为您担心会产生大量开销.

Keeping an index on the array of _id will vastly improve your queries' speed on the side where you fear there will be significant overhead.

但仅当此关系是进行大量查询的重要关系时才保留 index.如果这只是您项目的一个附带功能,您也可以没有索引.

But keep the index only if this relation is an important relation with a lot of queries going on. If this is just a side feature of your project, you can do without an index too.

如果用户可以做很多事情并且有很多关系,那么您将在整个应用程序中不断需要该用户对象,因此如果您的应用程序不是特定于项目的,最好不要将项目 ID 放入用户架构.但是因为我们只是放置了 id,所以它的开销并不大.无需担心.

If the user can do lots of stuff and has lots of relations, you will be needing that user object constantly throughout your app, so if your app isn't project specific, it would be better to not put the project ids in the user schema. But as we are just putting the ids, it isn't much of an overhead anyway. No need to worry about that.

两个数组上的Reg索引:是的,你当然可以.但是当您使用解决方案 3 时,您根本不需要索引,因为您不会执行查询来获取用户的项目列表或项目中的用户列表.解决方案 3 使阅读非常容易,但编写有点麻烦.但是正如您提到的,您的用例涉及reading>>writing,请使用解决方案 3,但始终存在数据不一致的危险,您需要注意这一点.

Reg index on both the arrays: Yes you can ofcourse. But when you go for solution 3, you don't need an index at all as you won't be doing a query to get the list of projects of a user or the list of users in a project. Solution 3 makes reading very easy but writing a bit cumbersome. But as you mentioned that your use case involves reading>>writing, go with solution 3 but there's always a danger of data inconsistency which you need to take care of.

索引只会让事情变得更快.浏览文档 并进行一些谷歌搜索.没有什么花哨.查询索引数组比普通数组高效.例如.让我们假设您使用解决方案 2.将项目 ID 存储在 project_ids 字段中.

Indexing just makes things faster. Go through the docs and do a bit of googling. Nothing fancy. Querying over indexed arrays is efficient than normal arrays. For ex. Let us assume you use solution 2. Store the project ids in the project_ids field.

您可以轻松获取用户的项目.这很简单.

You can get the projects of a user easily. This is straight forward.

但是为了获得project1的用户.您需要这样的查询.

But to get users of project1. You need to a query like this.

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.为了获取用户的项目,我们进行以下查询

Similary for solution 1. Each project has user_ids field.Let us assume we have a user1. To get the projects of user we do the folowing query

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 更好.在某些情况下,您可能需要没有项目的用户,但在没有用户的情况下需要项目的机会非常低.但这取决于您的具体用例.

If you are pondering over solution 1 vs solution 2, solution 1 is better I guess. There might be cases where you need user without his projects but the chances of requiring the project without users is pretty low. But it depends on your exact use case.

这篇关于与 nosql 的多对多关系(mongodb 和 mongoose)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆