我有两个文档,用户和项目,一个用户可以有很多项目,一个项目可以有很多用户,所以在我的情况下,我有4个选项:
1 – An array of id_user inside project document.
2 – An array of id_project inside user document.
3 – An array of id_user inside project document && An array of
id_project inside user document.4 – A third table mapping user and project relationship(like a
relational database).
选项1和2是不可用的,因为想想在选项1的情况下,如果我想从用户找到所有项目,我将不得不在用户的每个项目文档数组中查找此用户标识(遍历此数组在每个项目中)这绝对不是一个好办法.
选项3是好的,但我将不得不进行某种交易,以确保两个文件都将被写入,这并不是那么糟糕,因为这两个文件的读取会比写入的多得多
选项4更简单,因为当我将一个用户添加到项目中时,只需添加一个新的文档,这两个id都是(这是我想的很好的解决方案,因为我不需要关心事务,这是一个很好的解决方案)
那么,最好的解决方案是什么?
要在解决方案1和2之间进行选择,您需要考虑读取频率.您是否需要更频繁地使用用户的项目或使用项目,并根据需要进行选择.如果您觉得两者频率相对相同,则最好将用户对象尽可能少地聚集在一起.无论您选择什么选项,请考虑在存储_ids(项目或用户)的数组中保留索引.
例如
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数组上保持索引会大大提高您的查询速度,您可能会担心这会导致重大开销.
但是只有当这个关系与许多查询的重要关系时才保持索引.如果这只是您的项目的一个侧面功能,您也可以没有索引.
如果用户可以做很多事情并且有很多关系,那么您将在整个应用程序中不断地需要该用户对象,所以如果您的应用程序不是项目特定的,那么最好不要将项目ID放在用户模式中.但是,正如我们只是把ids,它不是太多的架空.没必要担心.
两个数组的Reg索引:是的,你可以.但是当你去解决方案3时,你根本不需要一个索引,因为你不会做一个查询来获取一个用户的项目列表或一个项目中的用户列表.解决方案3使阅读变得非常容易,但写得有点麻烦.但是正如你所提到的,你的用例涉及阅读>>写作,请使用解决方案3,但总是有数据不一致的危险,您需要照顾.
索引只是使事情更快.通过the docs,做一些谷歌搜索.没什么好想的查询索引数组比正常数组有效.例如让我们假设你使用解决方案2.
将项目ID存储在project_ids字段中.
您可以轻松地获得用户的项目.这是直接的.
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},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更好我猜.在没有他的项目的情况下,您可能需要用户,但没有用户需要项目的机会相当低.但这取决于你的确切用例.