2016-11-21 59 views
2

我错过了什么吗?与传统数据库相比,为什么ORM需要更多努力来同步关系。以下面为例。Mongoose和MongoDB,与关系不同步

var UserSchema = new Schema({ 
    username: {type: String, required: true, index:{unique:true}}, 
    password: {type: String, required: true}, 
    events: [{type: Schema.Types.ObjectId, ref:'Event'}] 
}); 

var EventSchema = new Schema({ 
    _creator: {type:Schema.Types.ObjectId, ref: 'User'}, 
    post: {type: String, required: true} 
}); 

UserSchema有很多事件,其中事件模式属于一个用户又名创建者。

.delete(function(req, res){ 
     Event.remove({ 
      _id:req.params.event_id 
     },function(err,response){ 
      if(err) 
       res.send(err); 
      res.json({message:'Successfully Deleted'}); 
     }); 
    }); 

如果我创建了一个事件,并添加用户对象,创建者,它成功地加入了表,但如果我删除的事件。该事件不再显示,但ID仍显示在用户查询下。

下面是我的用户查询的样子后,我删除属于用户

[ 
    { 
    "_id": "5831be814f8df40646fed954", 
    "password": "$2a$10$MNbwpj0qi9.rhEPmCHe5mOc8crrEo/CwbxVSbjjLSw28GdcQ0O6Um", 
    "username": "klaus", 
    "__v": 1, 
    "events": [ 
     "5831c216a3d6810692bdf381" 
    ] 
    } 
] 

我怎么会去从用户模式移除ID事件?不将事件模式与用户模式链接起来会更好吗?为什么这是屁股疼痛,为什么这是未来?

+0

我更新[我的回答(http://stackoverflow.com/questions/40723019/mongoose-and-mongodb-out-of-sync-with-relationships/40723300#40723300)。我希望现在更有帮助。 – rsp

回答

2

这不是一个ORM,没有连接,也没有表。您试图使用Mongo,因为它是一个关系数据库,事实并非如此。

回答你的问题“为什么这是屁股疼痛,为什么这是未来?” - 除非您将Mongo识别为文档存储并将其用于此目的,否则您将始终感到失望。

现在,一些背景。在关系数据库中,您可以拥有外键,约束和触发器,这些外键,约束和触发器可以确保您在其他关系中引用元组时不会删除元组,或者可以将元组删除,但操作级联并删除现在指向不存在的密钥并导致数据库不一致。这通常也在一个事务中完成,因此您可以确定没有人会看到数据的不一致视图。

有了Mongo,就没有这样的保证。有validations,但那些可以是bypassed

当您存储对另一个文档的引用时,它只是一个String或ObjectId实例,不必在任何地方存在于数据库中。 “引用提供了比嵌入更多的灵活性,但是,客户端应用程序必须发出后续查询来解析引用,换句话说,规范化的数据模型可能需要更多的往返服务器。 (请参阅Normalized Data Models)换句话说,不仅强制关系的有效性,实际的“加入”发生在客户端,而不是数据库中,在单独的查询中(可能存在竞争条件)。

此外,您没有事务,因此无法在一次原子操作中删除文档及其对它的所有引用。但即使可能,Mongo中仍然没有模式,因此无论何时将ObjectId作为某个字段的值,Mongo都不知道应该引用哪个集合,因此它甚至不知道在何处寻找。

这意味着您需要在删除可能在其他文档中引用的数据后手动清除。但是由于数据库不会告诉你你正在删除的文档的ObjectId可能存储在哪里,所以你有责任了解并确保你自己保持数据库的一致性。

现在,为模式。 Mongo中确实没有模式的概念。在Mongoose中有模式,但在Mongo中没有。“MongoDB中的数据有一个灵活模式。集合不执行文档结构。” (见Data Modeling)拥有这个“灵活的模式”意味着根本没有模式。在实践中,模式只存在于Mongoose的客户端。您可以拥有一个很好的Mongoose模式,但是如果您有多个应用程序连接到同一个数据库(或者甚至是同一个应用程序的两个版本),那么这些应用程序可能会有不一致的模式,并可能以静默方式损坏您的数据库。

考虑到这一切,我建议只有当您不需要保证一致性,事务,外键,联接,强制模式和其他功能时,您可能会熟悉使用其他数据库时,否则就像你描述的那样它总是会很痛苦。

+0

我将它识别为文档存储。但开发人员将它用作数据库的权利?还是我误会了?我不能接受这个答案。 – numerical25

+0

@ numerical25开发人员将它用作数据库,因为Mongo **是**数据库。这不仅仅是一个**关系数据库。它没有连接,没有表,没有事务,而且Mongoose不是对象关系映射器。说真的,Mongo并不是一个非常复杂的数据库,如果你认为它会令你失望。如果你想要“未来”,那么也许尝试RethinkDB或Cassandra。或者如果你只想要一个好的数据库,可以坚持到Postgres。说真的,我想在这里帮忙。回答您的问题的唯一答案不是鼓励您在未来回答问题的好方法。 – rsp