如何解决mongo中的外键?
| 如何在MongoDB中设计这样的方案?我认为没有外键!解决方法
您可能对使用Mongoid或MongoMapper之类的ORM感兴趣。
http://mongoid.org/docs/relations/referenced/1-n.html
在像MongoDB这样的NoSQL数据库中,没有\'tables \'而是集合。文档在“集合”中分组。您可以在一个集合中拥有任何类型的文档以及任何类型的数据。基本上,在NoSQL数据库中,由您决定如何组织数据及其关系(如果有)。
Mongoid和MongoMapper所做的是为您提供便捷的方法来轻松建立关系。查看我给您的链接,并询问任何事情。
编辑:
在mongoid中,您将这样编写方案:
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中设计这样的表?
首先,要澄清一些命名约定。 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\'
}
显然,简的课程列表指向一些特定的课程。数据库不对系统应用任何约束(即:外键约束),因此不存在“级联删除”或“级联更新”。但是,数据库确实包含正确的信息。
此外,MongoDB具有DBRef标准,可帮助标准化这些引用的创建。实际上,如果您查看该链接,它就有一个类似的示例。
我该如何解决这个任务?
需要明确的是,MongoDB不是关系型的。没有标准的“标准格式”。您应该对数据库进行建模,使其适合存储的数据和要运行的查询。
, 我们可以在MongoDB中定义所谓的“ 5”。但是,我们需要自己维护数据完整性。例如,
student
{
_id: ObjectId(...),courses: [\'bio101\',\'bio102\'] // <= ids of the courses
}
course
{
_id: \'bio101\',description: \'Introduction to biology\'
}
“ѭ7”字段包含“ѭ8”个课程。定义一对多关系很容易。但是,如果要检索学生Jane
的课程名称,则需要执行另一项操作以通过_id
检索course
文档。
如果删除了课程“ 12”,我们需要执行另一项操作来更新“ 14”文档中的“ 7”字段。
更多:MongoDB模式设计
MongoDB的文档类型性质支持定义关系的灵活方法。定义一对多关系:
嵌入式文件
适合一对几。
优点:无需对另一个文档执行其他查询。
缺点:无法单独管理嵌入文档的实体。
例:
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
}
实际上,ѭ19是logmsg
的父代。鉴于日志消息为数十亿字节,因此引用“ 19” id可以节省大量空间。
参考文献:
MongoDB模式设计的6条经验法则:第1部分
MongoDB模式设计的6条经验法则:第2部分
MongoDB模式设计的6条经验法则:第3部分
使用文档参考建立一对多关系模型
, 摘自The Little MongoDB书
使用联接的另一种替代方法是对数据进行非规范化。历史上,非规范化是为
对性能敏感的代码,或应该对数据进行快照的时间(例如在审核日志中)。但是,随着
NoSQL越来越流行,其中许多都没有联接,作为规范建模的一部分的非规范化正变得越来越
越来越普遍。这并不意味着您应该在每个文档中复制每条信息。然而,
与其让担心重复数据驱动您的设计决策,不如考虑基于
信息属于什么文件。
所以,
student
{
_id: ObjectId(...),courses: [
{
name: \'Biology 101\',mark: 85,id:bio101
},]
}
如果它是RESTful API数据,则用指向课程资源的GET链接替换课程ID。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。