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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-01 10:57:31  来源:igfitidea点击:

Foreign keys in mongo?

sqlmongodbforeign-keysnosql

提问by Mark Pegasov

enter image description here

在此处输入图片说明

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 collectionsinstead 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 keyin 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 coursesfield contains _ids 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 coursedocument via _id.

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

If the course bio101is removed, we need to perform another operation to update the coursesfield in the studentdocument.

如果课程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

嵌入文件

  1. Suitable for one-to-few.
  2. Advantage: no need to perform additional queries to another document.
  3. Disadvantage: cannot manage the entity of embedded documents individually.
  1. 适合一对多。
  2. 优点:不需要对另一个文档执行额外的查询。
  3. 缺点:无法单独管理嵌入文档的实体。

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/courseexample 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 hostis the parent of a logmsg. Referencing to the hostid saves much space given that the log messages are squillions.

实际上, ahost是a的父级logmsghost鉴于日志消息是 squillions,引用id 可以节省很多空间。

References:

参考:

  1. 6 Rules of Thumb for MongoDB Schema Design: Part 1
  2. 6 Rules of Thumb for MongoDB Schema Design: Part 2
  3. 6 Rules of Thumb for MongoDB Schema Design: Part 3
  4. Model One-to-Many Relationships with Document References
  1. MongoDB 模式设计的 6 条经验法则:第 1 部分
  2. MongoDB 模式设计的 6 条经验法则:第 2 部分
  3. MongoDB 模式设计的 6 条经验法则:第 3 部分
  4. 使用文档引用建立一对多关系模型

回答by ZAky

From The Little MongoDB Book

来自MongoDB 小书

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 链接