Mongo中的外键?

在这里输入图像说明

我如何在MongoDB中devise这样的scheme? 我觉得没有外键!

您可能有兴趣使用像Mongoid或MongoMapper的ORM。

http://mongoid.org/docs/relations/referenced/1-n.html

在像MongoDB这样的NoSQL数据库中,不存在“表”,而是文档。 文档被分组在集合中。 您可以将任何种类的文档与任何种类的数据集中在一个集合中。 基本上,在NoSQL数据库中,由您决定如何组织数据及其关系(如果有的话)。

Mongoid和MongoMapper做的是为您提供便捷的方法来build立关系。 看看我给你的链接,并问任何事情。

编辑:

在mongoid中,你会这样写你的scheme:

class Student include Mongoid::Document field :name embeds_many :addresses embeds_many :scores end class Address include Mongoid::Document field :address field :city field :state field :postalCode embedded_in :student end class Score include Mongoid::Document belongs_to :course field :grade, type: Float embedded_in :student end class Course include Mongoid::Document field :name has_many :scores end 

编辑:

 > db.foo.insert({group:"phones"}) > db.foo.find() { "_id" : ObjectId("4df6539ae90592692ccc9940"), "group" : "phones" } { "_id" : ObjectId("4df6540fe90592692ccc9941"), "group" : "phones" } >db.foo.find({'_id':ObjectId("4df6539ae90592692ccc9940")}) { "_id" : ObjectId("4df6539ae90592692ccc9940"), "group" : "phones" } 

您可以使用该ObjectId为了做文件之间的关系。

如何在mongodb中devise这样的表格?

首先,澄清一些命名约定。 MongoDB使用collections而不是tables

我觉得没有外键!

采取以下模式:

 student { _id: ObjectId(...), name: 'Jane', courses: [ { course: 'bio101', mark: 85 }, { course: 'chem101', mark: 89 } ] } course { _id: 'bio101', name: 'Biology 101', description: 'Introduction to biology' } 

Jane的课程清单明确指出了一些具体的课程。 数据库不会对系统应用任何约束( 即:外键约束 ),所以没有“级联删除”或“级联更新”。 但是,数据库确实包含正确的信息。

另外,MongoDB有一个DBRef标准来帮助标准化这些引用的创build。 事实上,如果你看一下这个链接,它也有一个类似的例子。

我怎样才能解决这个任务?

清楚的是,MongoDB不是关系型的。 没有标准的“正常forms”。 您应该build立适合您存储的数据和您打算运行的查询的数据库模型。

从小MongoDB书

使用连接的另一种方法是对数据进行非规范化处理。 历史上,非规范化是为性能敏感的代码保留的,或者数据应该被快照的时候(比如在审计日志中)。 然而,随着NoSQL越来越stream行,其中许多没有连接,作为正常build模一部分的非规范化变得越来越普遍。 这并不意味着您应该复制每个文档中的每一条信息。 但是,不要担心重复数据会影响您的devise决策,请考虑根据属于哪个文档的信息来build模数据。

所以,

 student { _id: ObjectId(...), name: 'Jane', courses: [ { name: 'Biology 101', mark: 85, id:bio101 }, ] } 

如果它是一个RESTful API数据,则用课程资源的GET链接replace课程ID

我们可以在MongoDB中定义所谓的foreign key 。 但是,我们需要通过OURSELVES来维护数据的完整性。 例如,

 student { _id: ObjectId(...), name: 'Jane', courses: ['bio101', 'bio102'] // <= ids of the courses } course { _id: 'bio101', name: 'Biology 101', description: 'Introduction to biology' } 

courses领域包含_id的课程。 定义一个一对多的关系很容易。 但是,如果我们要检索学生Jane的课程名称,则需要执行另一个操作以通过_id检索course文档。

如果删除了bio101课程,我们需要执行另一个操作来更新student文档中的courses字段。

更多:MongoDB架构devise

MongoDB的文档types支持定义关系的灵活方式。 定义一个一对多的关系:

embedded的文件

  1. 适合一对多。
  2. 优点:不需要对另一个文档执行额外的查询。
  3. 缺点:不能单独pipe理embedded式文档的实体。

例:

 student { name: 'Kate Monster', addresses : [ { street: '123 Sesame St', city: 'Anytown', cc: 'USA' }, { street: '123 Avenue Q', city: 'New York', cc: 'USA' } ] } 

儿童参考

像上面的student / course例子一样。

家长参考

适用于一对多的情况,如日志消息。

 host { _id : ObjectID('AAAB'), name : 'goofy.example.com', ipaddr : '127.66.66.66' } logmsg { time : ISODate("2014-03-28T09:42:41.382Z"), message : 'cpu is on fire!', host: ObjectID('AAAB') // Reference to the Host document } 

实际上, hostlogmsg的父logmsg 。 由于日志消息是squillions,所以引用host ID会节省很多空间。

参考文献:

  1. MongoDB模式devise的6条经验法则:第一部分
  2. MongoDB模式devise的6条经验法则:第2部分
  3. MongoDB模式devise的6条经验法则:第3部分
  4. 模型与文档引用的一对多关系