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的文件
- 适合一对多。
- 优点:不需要对另一个文档执行额外的查询。
- 缺点:不能单独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 }
实际上, host
是logmsg
的父logmsg
。 由于日志消息是squillions,所以引用host
ID会节省很多空间。
参考文献:
- MongoDB模式devise的6条经验法则:第一部分
- MongoDB模式devise的6条经验法则:第2部分
- MongoDB模式devise的6条经验法则:第3部分
- 模型与文档引用的一对多关系