SQL mongo 中的外键?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6334048/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Foreign keys in mongo?
提问by Mark Pegasov
How do I design a scheme such this in MongoDB? I think there are no foreign keys!
如何在 MongoDB 中设计这样的方案?我认为没有外键!
采纳答案by Nerian
You may be interested in using a ORM like Mongoid or MongoMapper.
您可能对使用像 Mongoid 或 MongoMapper 这样的 ORM 感兴趣。
http://mongoid.org/docs/relations/referenced/1-n.html
http://mongoid.org/docs/relations/referenced/1-n.html
In a NoSQL database like MongoDB there are not 'tables' but collections. Documents are grouped inside Collections. You can have any kind of document – with any kind of data – in a single collection. Basically, in a NoSQL database it is up to you to decide how to organise the data and its relations, if there are any.
在像 MongoDB 这样的 NoSQL 数据库中,没有“表”而是集合。文档分组在集合内。您可以在单个集合中拥有任何类型的文档——包含任何类型的数据。基本上,在 NoSQL 数据库中,由您决定如何组织数据及其关系(如果有)。
What Mongoid and MongoMapper do is to provide you with convenient methods to set up relations quite easily. Check out the link I gave you and ask any thing.
Mongoid 和 MongoMapper 所做的是为您提供方便的方法来非常轻松地建立关系。查看我给你的链接并询问任何问题。
Edit:
编辑:
In mongoid you will write your scheme like this:
在 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
Edit:
编辑:
> 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" }
You can use that ObjectId in order to do relations between documents.
您可以使用该 ObjectId 来处理文档之间的关系。
回答by Gates VP
How to design table like this in mongodb?
如何在mongodb中设计这样的表?
First, to clarify some naming conventions. MongoDB uses collections
instead of tables
.
首先,澄清一些命名约定。MongoDB 使用collections
而不是tables
.
I think there are no foreign keys!
我认为没有外键!
Take the following model:
采取以下模型:
student
{
_id: ObjectId(...),
name: 'Jane',
courses: [
{ course: 'bio101', mark: 85 },
{ course: 'chem101', mark: 89 }
]
}
course
{
_id: 'bio101',
name: 'Biology 101',
description: 'Introduction to biology'
}
Clearly Jane's course list points to some specific courses. The database does not apply any constraints to the system (i.e.: foreign key constraints), so there are no "cascading deletes" or "cascading updates". However, the database does contain the correct information.
显然,Jane 的课程列表指向了一些特定的课程。数据库不对系统应用任何约束(即:外键约束),因此没有“级联删除”或“级联更新”。但是,数据库确实包含正确的信息。
In addition, MongoDB has a DBRef standardthat helps standardize the creation of these references. In fact, if you take a look at that link, it has a similar example.
此外,MongoDB 有一个DBRef 标准,有助于标准化这些引用的创建。事实上,如果你看一下那个链接,它有一个类似的例子。
How can I solve this task?
我该如何解决这个任务?
To be clear, MongoDB is not relational. There is no standard "normal form". You should model your database appropriate to the data you store and the queries you intend to run.
需要明确的是,MongoDB 不是关系型的。没有标准的“范式”。您应该为您的数据库建模,以适合您存储的数据和您打算运行的查询。
回答by Joy
We can define the so-called foreign key
in MongoDB. However, we need to maintain the data integrity BY OURSELVES. For example,
我们可以foreign key
在MongoDB中定义所谓的。然而,我们需要保持数据的完整性由我们自己。例如,
student
{
_id: ObjectId(...),
name: 'Jane',
courses: ['bio101', 'bio102'] // <= ids of the courses
}
course
{
_id: 'bio101',
name: 'Biology 101',
description: 'Introduction to biology'
}
The courses
field contains _id
s of courses. It is easy to define a one-to-many relationship. However, if we want to retrieve the course names of student Jane
, we need to perform another operation to retrieve the course
document via _id
.
该courses
字段包含_id
s 个课程。定义一对多关系很容易。但是,如果我们要检索 student 的课程名称Jane
,则需要执行另一个操作以course
通过检索文档_id
。
If the course bio101
is removed, we need to perform another operation to update the courses
field in the student
document.
如果课程bio101
被移除,我们需要执行另一个操作来更新文档中的courses
字段student
。
More: MongoDB Schema Design
更多:MongoDB 模式设计
The document-typed nature of MongoDB supports flexible ways to define relationships. To define a one-to-many relationship:
MongoDB 的文档类型特性支持定义关系的灵活方式。定义一对多关系:
Embedded document
嵌入文件
- Suitable for one-to-few.
- Advantage: no need to perform additional queries to another document.
- Disadvantage: cannot manage the entity of embedded documents individually.
- 适合一对多。
- 优点:不需要对另一个文档执行额外的查询。
- 缺点:无法单独管理嵌入文档的实体。
Example:
例子:
student
{
name: 'Kate Monster',
addresses : [
{ street: '123 Sesame St', city: 'Anytown', cc: 'USA' },
{ street: '123 Avenue Q', city: 'New York', cc: 'USA' }
]
}
Child referencing
儿童参考
Like the student
/course
example above.
就像上面的student
/course
示例一样。
Parent referencing
父引用
Suitable for one-to-squillions, such as log messages.
适用于一对squillions,例如日志消息。
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
}
Virtually, a host
is the parent of a logmsg
. Referencing to the host
id saves much space given that the log messages are squillions.
实际上, ahost
是a的父级logmsg
。host
鉴于日志消息是 squillions,引用id 可以节省很多空间。
References:
参考:
回答by ZAky
Yet another alternative to using joins is to denormalize your data. Historically, denormalization was reserved for performance-sensitive code, or when data should be snapshotted (like in an audit log). However, with the ever- growing popularity of NoSQL, many of which don't have joins, denormalization as part of normal modeling is becoming increasingly common. This doesn't mean you should duplicate every piece of information in every document. However, rather than letting fear of duplicate data drive your design decisions, consider modeling your data based on what information belongs to what document.
使用连接的另一种替代方法是对数据进行非规范化。从历史上看,非规范化是为性能敏感的代码保留的,或者当数据应该被快照时(比如在审计日志中)。然而,随着 NoSQL 的日益普及,其中许多没有连接,作为正常建模一部分的非规范化变得越来越普遍。这并不意味着您应该复制每个文档中的每条信息。但是,与其让对重复数据的恐惧驱动您的设计决策,不如考虑根据哪些信息属于哪个文档来对数据进行建模。
So,
所以,
student
{
_id: ObjectId(...),
name: 'Jane',
courses: [
{
name: 'Biology 101',
mark: 85,
id:bio101
},
]
}
If its a RESTful API data, replace the course id with a GET link to the course resource
如果是 RESTful API 数据,请将课程 ID 替换为指向课程资源的 GET 链接