MongoDB一对多关系 [英] MongoDB One to Many Relationship

查看:227
本文介绍了MongoDB一对多关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始学习MongoDB,有一次我问自己如何解决MongoDB中的一对多"关系设计.在搜索时,我在其他帖子/文章中发现了很多评论,例如您正在思考关系". 好的我同意.在某些情况下,信息重复不会成为问题,例如CLIENTS-ORDERS示例.

I’m starting to learn MongoDB and I at one moment I was asking myself how to solve the "one to many" relationship design in MongoDB. While searching, I found many comments in other posts/articles like " you are thinking relational ". Ok, I agree. There will be some cases like duplication of information won’t be a problem, like in for example, CLIENTS-ORDERS example.

但是,假设您有以下表:ORDERS,该表具有嵌入式DETAIL结构以及客户购买的PRODUCTS. 因此,对于一件事或另一件事,您需要更改已经嵌入到多个订单中的产品名称(或另一种信息).

But, suppose you have the tables: ORDERS, that has an embedded DETAIL structure with the PRODUCTS that a client bought. So for one thing or another, you need to change a product name (or another kind of information) that is already embedded in several orders.

最后,您被迫在MongoDB中进行一对多的冲突(这意味着将ObjectID字段作为另一个集合的链接),这样您就可以解决这个简单的问题,不是吗? 但是,每当我发现有关此问题的文章/评论时,都会说这将是Mongo的性能故障.有点令人失望

At the end, you are force to do a one-to-many relashionship in MongoDB (that means, putting the ObjectID field as link to another collection) so you can solve this simple problem, don’t you ? But every time I found some article/comment about this, it says that will be a performance fault in Mongo. It’s kind of disappointing

在MongoDB中还有另一种方法可以解决/设计这一问题而不会出现性能故障吗?

Is there another way to solve/design this without performance fault in MongoDB ?

推荐答案

问题是您过度标准化了数据.订单由客户定义,该客户居住在给定时间的某个位置,并支付一定的价格,该价格在订单生效时有效(在整个应用程序生命周期中可能会发生重大变化,无论如何您都必须记录在案)其他参数都仅在特定时间点有效.因此,要记录订单(双关语),您需要在该特定时间点保留所有数据.让我举一个例子:

The problem is that you over normalize your data. An order is defined by a customer, who lives at a certain place at the given point in time, pays a certain price valid at the time of the order (which might heavily change over the application lifetime and which you have to document anyway and several other parameters which are all valid only in a certain point of time. So to document an order (pun intended), you need to persist all data for that certain point in time. Let me give you an example:

{ _id: "order123456789",
  date: ISODate("2014-08-01T16:25:00.141Z"),
  customer: ObjectId("53fb38f0040980c9960ee270"),
  items:[ ObjectId("53fb3940040980c9960ee271"),
          ObjectId("53fb3940040980c9960ee272"),
          ObjectId("53fb3940040980c9960ee273")
         ],
 Total:400
 }

现在,只要客户和项目的详细信息都没有改变,您就可以复制此订单的发送地,订单的价格等.但是现在,如果客户更改地址,会发生什么?还是一件商品的价格改变了?您需要跟踪它们各自文档中的那些更改.像这样存储订单将容易并且足够有效:

Now, as long as neither the customer nor the details of the items change, you are able to reproduce where this order was sent to, what the prices on the order were and alike. But now what happens if the customer changes it's address? Or if the price of an item changes? You would need to keep track of those changes in their respective documents. It would be much easier and sufficiently efficient to store the order like:

{
  _id: "order987654321",
  date: ISODate("2014-08-01T16:25:00.141Z"),
  customer: {
               userID: ObjectId("53fb3940040980c9960ee283"),
               recipientName: "Foo Bar"
               address: {
                          street: "742 Evergreen Terrace",
                          city: "Springfield",
                          state: null
                         }
            },
  items: [
    {count:1, productId:ObjectId("53fb3940040980c9960ee300"), price: 42.00 },
    {count:3, productId:ObjectId("53fb3940040980c9960ee301"), price: 0.99},
    {count:5, productId:ObjectId("53fb3940040980c9960ee302"), price: 199.00}
  ]
}

借助此数据模型和聚合管道的使用,您具有以下优点:

With this data model and the usage of aggregation pipelines, you have several advantages:

  1. 您不需要独立跟踪价格和地址,名称更改或客户的礼物购买-它已被记录在案.
  2. 使用聚合管道,您可以创建价格趋势,而无需独立存储定价数据.您只需在订单文档中存储商品的当前价格.
  3. 甚至可以使用非常简单的汇总来完成复杂的汇总,例如价格弹性,州/市的营业额等.

通常,可以肯定地说,在面向文档的数据库中,将来可能会发生更改且此更改会产生不同语义的每个属性或字段都应存储在文档内部.将来可能会发生任何更改但不涉及语义的所有内容(示例中为用户密码)都可以通过GUID进行链接.

In general, it is safe to say that in a document oriented database, every property or field which is subject to change in the future and this change would create a different semantic meaning should be stored inside the document. Everything which is subject to change in the future but doesn't touch the semantic meaning (the users password in the example) may be linked via a GUID.

这篇关于MongoDB一对多关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆